beth-copilot 1.0.14 → 1.0.16
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 +195 -177
- package/README.md +528 -185
- package/bin/cli.js +47 -0
- package/dist/cli/commands/doctor.e2e.test.d.ts +8 -0
- package/dist/cli/commands/doctor.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/doctor.e2e.test.js +428 -0
- package/dist/cli/commands/doctor.e2e.test.js.map +1 -0
- package/dist/cli/commands/doctor.test.js +1 -1
- package/dist/cli/commands/help.e2e.test.d.ts +9 -0
- package/dist/cli/commands/help.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/help.e2e.test.js +150 -0
- package/dist/cli/commands/help.e2e.test.js.map +1 -0
- package/dist/cli/commands/init.test.d.ts +6 -0
- package/dist/cli/commands/init.test.d.ts.map +1 -0
- package/dist/cli/commands/init.test.js +289 -0
- package/dist/cli/commands/init.test.js.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.d.ts +9 -0
- package/dist/cli/commands/mcp.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.js +139 -0
- package/dist/cli/commands/mcp.e2e.test.js.map +1 -0
- package/dist/cli/commands/pipeline.e2e.test.d.ts +9 -0
- package/dist/cli/commands/pipeline.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/pipeline.e2e.test.js +192 -0
- package/dist/cli/commands/pipeline.e2e.test.js.map +1 -0
- package/dist/cli/commands/quickstart.test.d.ts +6 -0
- package/dist/cli/commands/quickstart.test.d.ts.map +1 -0
- package/dist/cli/commands/quickstart.test.js +232 -0
- package/dist/cli/commands/quickstart.test.js.map +1 -0
- package/dist/core/agents/frontmatter.test.d.ts +8 -0
- package/dist/core/agents/frontmatter.test.d.ts.map +1 -0
- package/dist/core/agents/frontmatter.test.js +589 -0
- package/dist/core/agents/frontmatter.test.js.map +1 -0
- package/dist/core/agents/handoffs.test.d.ts +8 -0
- package/dist/core/agents/handoffs.test.d.ts.map +1 -0
- package/dist/core/agents/handoffs.test.js +320 -0
- package/dist/core/agents/handoffs.test.js.map +1 -0
- package/dist/core/agents/loader.test.js +1 -1
- package/dist/core/agents/suite.test.d.ts +8 -0
- package/dist/core/agents/suite.test.d.ts.map +1 -0
- package/dist/core/agents/suite.test.js +207 -0
- package/dist/core/agents/suite.test.js.map +1 -0
- package/dist/core/agents/tools.test.d.ts +8 -0
- package/dist/core/agents/tools.test.d.ts.map +1 -0
- package/dist/core/agents/tools.test.js +332 -0
- package/dist/core/agents/tools.test.js.map +1 -0
- package/dist/core/context.d.ts +171 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +353 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/context.test.d.ts +8 -0
- package/dist/core/context.test.d.ts.map +1 -0
- package/dist/core/context.test.js +253 -0
- package/dist/core/context.test.js.map +1 -0
- package/dist/core/handoffs.d.ts +151 -0
- package/dist/core/handoffs.d.ts.map +1 -0
- package/dist/core/handoffs.js +220 -0
- package/dist/core/handoffs.js.map +1 -0
- package/dist/core/handoffs.test.d.ts +8 -0
- package/dist/core/handoffs.test.d.ts.map +1 -0
- package/dist/core/handoffs.test.js +231 -0
- package/dist/core/handoffs.test.js.map +1 -0
- package/dist/core/orchestrator.d.ts +246 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +514 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/orchestrator.test.d.ts +8 -0
- package/dist/core/orchestrator.test.d.ts.map +1 -0
- package/dist/core/orchestrator.test.js +517 -0
- package/dist/core/orchestrator.test.js.map +1 -0
- package/dist/core/router.d.ts +102 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +178 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/router.test.d.ts +8 -0
- package/dist/core/router.test.d.ts.map +1 -0
- package/dist/core/router.test.js +215 -0
- package/dist/core/router.test.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/init.test.js +288 -0
- package/dist/providers/azure.d.ts +147 -0
- package/dist/providers/azure.d.ts.map +1 -0
- package/dist/providers/azure.js +491 -0
- package/dist/providers/azure.js.map +1 -0
- package/dist/providers/azure.test.d.ts +11 -0
- package/dist/providers/azure.test.d.ts.map +1 -0
- package/dist/providers/azure.test.js +330 -0
- package/dist/providers/azure.test.js.map +1 -0
- package/dist/providers/config.d.ts +87 -0
- package/dist/providers/config.d.ts.map +1 -0
- package/dist/providers/config.js +193 -0
- package/dist/providers/config.js.map +1 -0
- package/dist/providers/config.test.d.ts +7 -0
- package/dist/providers/config.test.d.ts.map +1 -0
- package/dist/providers/config.test.js +370 -0
- package/dist/providers/config.test.js.map +1 -0
- package/dist/providers/index.d.ts +18 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +14 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/interface.d.ts +191 -0
- package/dist/providers/interface.d.ts.map +1 -0
- package/dist/providers/interface.js +94 -0
- package/dist/providers/interface.js.map +1 -0
- package/dist/providers/retry.d.ts +128 -0
- package/dist/providers/retry.d.ts.map +1 -0
- package/dist/providers/retry.js +205 -0
- package/dist/providers/retry.js.map +1 -0
- package/dist/providers/retry.test.d.ts +7 -0
- package/dist/providers/retry.test.d.ts.map +1 -0
- package/dist/providers/retry.test.js +439 -0
- package/dist/providers/retry.test.js.map +1 -0
- package/dist/providers/streaming.d.ts +157 -0
- package/dist/providers/streaming.d.ts.map +1 -0
- package/dist/providers/streaming.js +233 -0
- package/dist/providers/streaming.js.map +1 -0
- package/dist/providers/streaming.test.d.ts +7 -0
- package/dist/providers/streaming.test.d.ts.map +1 -0
- package/dist/providers/streaming.test.js +372 -0
- package/dist/providers/streaming.test.js.map +1 -0
- package/dist/providers/types.d.ts +209 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +53 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/types.test.d.ts +7 -0
- package/dist/providers/types.test.d.ts.map +1 -0
- package/dist/providers/types.test.js +141 -0
- package/dist/providers/types.test.js.map +1 -0
- package/dist/tools/cli/beads.d.ts +27 -0
- package/dist/tools/cli/beads.d.ts.map +1 -0
- package/dist/tools/cli/beads.js +172 -0
- package/dist/tools/cli/beads.js.map +1 -0
- package/dist/tools/cli/beads.test.d.ts +8 -0
- package/dist/tools/cli/beads.test.d.ts.map +1 -0
- package/dist/tools/cli/beads.test.js +264 -0
- package/dist/tools/cli/beads.test.js.map +1 -0
- package/dist/tools/cli/editFile.d.ts +17 -0
- package/dist/tools/cli/editFile.d.ts.map +1 -0
- package/dist/tools/cli/editFile.js +125 -0
- package/dist/tools/cli/editFile.js.map +1 -0
- package/dist/tools/cli/editFile.test.d.ts +8 -0
- package/dist/tools/cli/editFile.test.d.ts.map +1 -0
- package/dist/tools/cli/editFile.test.js +177 -0
- package/dist/tools/cli/editFile.test.js.map +1 -0
- package/dist/tools/cli/readFile.d.ts +25 -0
- package/dist/tools/cli/readFile.d.ts.map +1 -0
- package/dist/tools/cli/readFile.js +118 -0
- package/dist/tools/cli/readFile.js.map +1 -0
- package/dist/tools/cli/readFile.test.d.ts +8 -0
- package/dist/tools/cli/readFile.test.d.ts.map +1 -0
- package/dist/tools/cli/readFile.test.js +194 -0
- package/dist/tools/cli/readFile.test.js.map +1 -0
- package/dist/tools/cli/search.d.ts +16 -0
- package/dist/tools/cli/search.d.ts.map +1 -0
- package/dist/tools/cli/search.js +261 -0
- package/dist/tools/cli/search.js.map +1 -0
- package/dist/tools/cli/search.test.d.ts +8 -0
- package/dist/tools/cli/search.test.d.ts.map +1 -0
- package/dist/tools/cli/search.test.js +172 -0
- package/dist/tools/cli/search.test.js.map +1 -0
- package/dist/tools/cli/subagent.d.ts +43 -0
- package/dist/tools/cli/subagent.d.ts.map +1 -0
- package/dist/tools/cli/subagent.js +99 -0
- package/dist/tools/cli/subagent.js.map +1 -0
- package/dist/tools/cli/subagent.test.d.ts +8 -0
- package/dist/tools/cli/subagent.test.d.ts.map +1 -0
- package/dist/tools/cli/subagent.test.js +190 -0
- package/dist/tools/cli/subagent.test.js.map +1 -0
- package/dist/tools/cli/terminal.d.ts +19 -0
- package/dist/tools/cli/terminal.d.ts.map +1 -0
- package/dist/tools/cli/terminal.js +164 -0
- package/dist/tools/cli/terminal.js.map +1 -0
- package/dist/tools/cli/terminal.test.d.ts +8 -0
- package/dist/tools/cli/terminal.test.d.ts.map +1 -0
- package/dist/tools/cli/terminal.test.js +161 -0
- package/dist/tools/cli/terminal.test.js.map +1 -0
- package/dist/tools/index.d.ts +25 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +41 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/interface.d.ts +64 -0
- package/dist/tools/interface.d.ts.map +1 -0
- package/dist/tools/interface.js +37 -0
- package/dist/tools/interface.js.map +1 -0
- package/dist/tools/interface.test.d.ts +7 -0
- package/dist/tools/interface.test.d.ts.map +1 -0
- package/dist/tools/interface.test.js +179 -0
- package/dist/tools/interface.test.js.map +1 -0
- package/dist/tools/mcp/bridge.d.ts +48 -0
- package/dist/tools/mcp/bridge.d.ts.map +1 -0
- package/dist/tools/mcp/bridge.js +128 -0
- package/dist/tools/mcp/bridge.js.map +1 -0
- package/dist/tools/mcp/bridge.test.d.ts +8 -0
- package/dist/tools/mcp/bridge.test.d.ts.map +1 -0
- package/dist/tools/mcp/bridge.test.js +300 -0
- package/dist/tools/mcp/bridge.test.js.map +1 -0
- package/dist/tools/mcp/client.d.ts +135 -0
- package/dist/tools/mcp/client.d.ts.map +1 -0
- package/dist/tools/mcp/client.js +263 -0
- package/dist/tools/mcp/client.js.map +1 -0
- package/dist/tools/mcp/client.test.d.ts +8 -0
- package/dist/tools/mcp/client.test.d.ts.map +1 -0
- package/dist/tools/mcp/client.test.js +390 -0
- package/dist/tools/mcp/client.test.js.map +1 -0
- package/dist/tools/registry.d.ts +82 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +99 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/registry.test.d.ts +7 -0
- package/dist/tools/registry.test.d.ts.map +1 -0
- package/dist/tools/registry.test.js +199 -0
- package/dist/tools/registry.test.js.map +1 -0
- package/dist/tools/suite.test.d.ts +11 -0
- package/dist/tools/suite.test.d.ts.map +1 -0
- package/dist/tools/suite.test.js +119 -0
- package/dist/tools/suite.test.js.map +1 -0
- package/dist/tools/types.d.ts +75 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +30 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/types.test.d.ts +7 -0
- package/dist/tools/types.test.d.ts.map +1 -0
- package/dist/tools/types.test.js +178 -0
- package/dist/tools/types.test.js.map +1 -0
- package/package.json +60 -56
- package/sbom.json +3302 -8
- package/templates/.github/agents/beth.agent.md +329 -329
- package/templates/.github/agents/developer.agent.md +572 -572
- package/templates/.github/agents/product-manager.agent.md +272 -272
- package/templates/.github/agents/researcher.agent.md +338 -338
- package/templates/.github/agents/security-reviewer.agent.md +465 -465
- package/templates/.github/agents/tester.agent.md +496 -496
- package/templates/.github/agents/ux-designer.agent.md +393 -393
- package/templates/mcp.json.example +4 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Tools and Model Validation Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for agent tools array and model field parsing/validation.
|
|
5
|
+
* Run with: node --test dist/core/agents/tools.test.js
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it } from 'node:test';
|
|
8
|
+
import assert from 'node:assert';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { loadAgents, loadAgent } from './loader.js';
|
|
11
|
+
// Test against templates directory for actual agent file tests
|
|
12
|
+
const TEMPLATES_AGENTS_DIR = join(process.cwd(), 'templates', '.github', 'agents');
|
|
13
|
+
/**
|
|
14
|
+
* All known tools defined in AgentTool type.
|
|
15
|
+
*/
|
|
16
|
+
const KNOWN_TOOLS = [
|
|
17
|
+
'codebase',
|
|
18
|
+
'readFile',
|
|
19
|
+
'editFiles',
|
|
20
|
+
'createFile',
|
|
21
|
+
'listDirectory',
|
|
22
|
+
'fileSearch',
|
|
23
|
+
'textSearch',
|
|
24
|
+
'runInTerminal',
|
|
25
|
+
'getTerminalOutput',
|
|
26
|
+
'problems',
|
|
27
|
+
'usages',
|
|
28
|
+
'runSubagent',
|
|
29
|
+
];
|
|
30
|
+
describe('Tools array validation', () => {
|
|
31
|
+
it('should accept valid tools array with known tools', () => {
|
|
32
|
+
const frontmatter = {
|
|
33
|
+
name: 'test-agent',
|
|
34
|
+
tools: ['codebase', 'readFile', 'editFiles'],
|
|
35
|
+
};
|
|
36
|
+
assert.ok(Array.isArray(frontmatter.tools));
|
|
37
|
+
assert.strictEqual(frontmatter.tools?.length, 3);
|
|
38
|
+
assert.ok(frontmatter.tools?.includes('codebase'));
|
|
39
|
+
assert.ok(frontmatter.tools?.includes('readFile'));
|
|
40
|
+
assert.ok(frontmatter.tools?.includes('editFiles'));
|
|
41
|
+
});
|
|
42
|
+
it('should accept empty tools array as valid', () => {
|
|
43
|
+
const frontmatter = {
|
|
44
|
+
name: 'test-agent',
|
|
45
|
+
tools: [],
|
|
46
|
+
};
|
|
47
|
+
assert.ok(Array.isArray(frontmatter.tools));
|
|
48
|
+
assert.strictEqual(frontmatter.tools?.length, 0);
|
|
49
|
+
});
|
|
50
|
+
it('should accept single tool in array', () => {
|
|
51
|
+
const frontmatter = {
|
|
52
|
+
name: 'test-agent',
|
|
53
|
+
tools: ['readFile'],
|
|
54
|
+
};
|
|
55
|
+
assert.ok(Array.isArray(frontmatter.tools));
|
|
56
|
+
assert.strictEqual(frontmatter.tools?.length, 1);
|
|
57
|
+
assert.strictEqual(frontmatter.tools?.[0], 'readFile');
|
|
58
|
+
});
|
|
59
|
+
it('should accept multiple tools in array', () => {
|
|
60
|
+
const tools = [
|
|
61
|
+
'codebase',
|
|
62
|
+
'readFile',
|
|
63
|
+
'editFiles',
|
|
64
|
+
'createFile',
|
|
65
|
+
'listDirectory',
|
|
66
|
+
'fileSearch',
|
|
67
|
+
'textSearch',
|
|
68
|
+
'runInTerminal',
|
|
69
|
+
'getTerminalOutput',
|
|
70
|
+
'problems',
|
|
71
|
+
'usages',
|
|
72
|
+
'runSubagent',
|
|
73
|
+
];
|
|
74
|
+
const frontmatter = {
|
|
75
|
+
name: 'test-agent',
|
|
76
|
+
tools,
|
|
77
|
+
};
|
|
78
|
+
assert.strictEqual(frontmatter.tools?.length, 12);
|
|
79
|
+
assert.deepStrictEqual(frontmatter.tools, KNOWN_TOOLS);
|
|
80
|
+
});
|
|
81
|
+
it('should accept unknown/custom tools (MCP tools)', () => {
|
|
82
|
+
const frontmatter = {
|
|
83
|
+
name: 'test-agent',
|
|
84
|
+
tools: [
|
|
85
|
+
'readFile',
|
|
86
|
+
'mcp_brave_search', // Custom MCP tool
|
|
87
|
+
'mcp_azure_deploy', // Custom MCP tool
|
|
88
|
+
'custom_internal_tool', // Custom internal tool
|
|
89
|
+
'fetch', // Non-standard tool
|
|
90
|
+
'githubRepo', // Non-standard tool
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
assert.strictEqual(frontmatter.tools?.length, 6);
|
|
94
|
+
assert.ok(frontmatter.tools?.includes('mcp_brave_search'));
|
|
95
|
+
assert.ok(frontmatter.tools?.includes('mcp_azure_deploy'));
|
|
96
|
+
assert.ok(frontmatter.tools?.includes('custom_internal_tool'));
|
|
97
|
+
});
|
|
98
|
+
it('should allow duplicate tools in array (no dedup in loader)', () => {
|
|
99
|
+
const frontmatter = {
|
|
100
|
+
name: 'test-agent',
|
|
101
|
+
tools: ['readFile', 'readFile', 'editFiles', 'editFiles', 'editFiles'],
|
|
102
|
+
};
|
|
103
|
+
assert.strictEqual(frontmatter.tools?.length, 5);
|
|
104
|
+
// Count duplicates
|
|
105
|
+
const readFileCount = frontmatter.tools?.filter((t) => t === 'readFile').length;
|
|
106
|
+
const editFilesCount = frontmatter.tools?.filter((t) => t === 'editFiles').length;
|
|
107
|
+
assert.strictEqual(readFileCount, 2);
|
|
108
|
+
assert.strictEqual(editFilesCount, 3);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe('Tools validation via loader', () => {
|
|
112
|
+
it('should fail when tools is not an array', async () => {
|
|
113
|
+
// Create a mock YAML content where tools is a string instead of array
|
|
114
|
+
// We test this by directly checking the validateFrontmatter behavior
|
|
115
|
+
// Since we can't easily create temp files, we verify the loader validates properly
|
|
116
|
+
// The loader validates in validateFrontmatter that tools must be an array if present
|
|
117
|
+
// This is documented behavior - tools: "readFile" should fail
|
|
118
|
+
// We can verify this behavior by checking a successfully loaded agent
|
|
119
|
+
const result = loadAgent(join(TEMPLATES_AGENTS_DIR, 'developer.agent.md'));
|
|
120
|
+
assert.ok(!('error' in result), 'Developer agent should load successfully');
|
|
121
|
+
const { agent } = result;
|
|
122
|
+
assert.ok(Array.isArray(agent.frontmatter.tools), 'tools should be an array');
|
|
123
|
+
});
|
|
124
|
+
it('should convert non-string values in tools array to strings', () => {
|
|
125
|
+
// The normalizeFrontmatter function in loader.ts does:
|
|
126
|
+
// frontmatter.tools = data.tools.map(String);
|
|
127
|
+
// This converts any value to string
|
|
128
|
+
// Test that the type system allows this and loader handles it
|
|
129
|
+
// When YAML parses numbers or other types, they get converted to strings
|
|
130
|
+
// Create frontmatter as if it came from YAML with mixed types
|
|
131
|
+
const rawData = {
|
|
132
|
+
name: 'test-agent',
|
|
133
|
+
tools: [123, true, 'readFile', null],
|
|
134
|
+
};
|
|
135
|
+
// Simulate what normalizeFrontmatter does
|
|
136
|
+
const normalizedTools = rawData.tools.map(String);
|
|
137
|
+
assert.deepStrictEqual(normalizedTools, ['123', 'true', 'readFile', 'null']);
|
|
138
|
+
assert.ok(normalizedTools.every((t) => typeof t === 'string'));
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('Model field validation', () => {
|
|
142
|
+
it('should accept Claude Opus 4.6 model', () => {
|
|
143
|
+
const frontmatter = {
|
|
144
|
+
name: 'test-agent',
|
|
145
|
+
model: 'Claude Opus 4.6',
|
|
146
|
+
};
|
|
147
|
+
assert.strictEqual(frontmatter.model, 'Claude Opus 4.6');
|
|
148
|
+
});
|
|
149
|
+
it('should accept claude-3-opus model', () => {
|
|
150
|
+
const frontmatter = {
|
|
151
|
+
name: 'test-agent',
|
|
152
|
+
model: 'claude-3-opus',
|
|
153
|
+
};
|
|
154
|
+
assert.strictEqual(frontmatter.model, 'claude-3-opus');
|
|
155
|
+
});
|
|
156
|
+
it('should accept any arbitrary string as model', () => {
|
|
157
|
+
const arbitraryModels = [
|
|
158
|
+
'gpt-4-turbo',
|
|
159
|
+
'gpt-4o',
|
|
160
|
+
'claude-3-sonnet',
|
|
161
|
+
'claude-3-haiku',
|
|
162
|
+
'gemini-pro',
|
|
163
|
+
'custom-fine-tuned-model-v2',
|
|
164
|
+
'my-local-llama',
|
|
165
|
+
'o1-preview',
|
|
166
|
+
'claude-3.5-sonnet-20241022',
|
|
167
|
+
];
|
|
168
|
+
for (const model of arbitraryModels) {
|
|
169
|
+
const frontmatter = {
|
|
170
|
+
name: 'test-agent',
|
|
171
|
+
model,
|
|
172
|
+
};
|
|
173
|
+
assert.strictEqual(frontmatter.model, model, `Should accept model: ${model}`);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
it('should result in undefined when model field is missing', () => {
|
|
177
|
+
const frontmatter = {
|
|
178
|
+
name: 'test-agent',
|
|
179
|
+
// model is intentionally omitted
|
|
180
|
+
};
|
|
181
|
+
assert.strictEqual(frontmatter.model, undefined);
|
|
182
|
+
assert.ok(!('model' in frontmatter) || frontmatter.model === undefined);
|
|
183
|
+
});
|
|
184
|
+
it('should accept empty string as model (edge case)', () => {
|
|
185
|
+
const frontmatter = {
|
|
186
|
+
name: 'test-agent',
|
|
187
|
+
model: '',
|
|
188
|
+
};
|
|
189
|
+
assert.strictEqual(frontmatter.model, '');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('Actual agent files tool configurations', () => {
|
|
193
|
+
it('should load all template agents without errors', () => {
|
|
194
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
195
|
+
assert.strictEqual(result.errors.length, 0, `Unexpected errors: ${JSON.stringify(result.errors)}`);
|
|
196
|
+
assert.ok(result.agents.length >= 7, `Expected at least 7 agents, got ${result.agents.length}`);
|
|
197
|
+
});
|
|
198
|
+
it('developer agent should have comprehensive tool set', () => {
|
|
199
|
+
const result = loadAgent(join(TEMPLATES_AGENTS_DIR, 'developer.agent.md'));
|
|
200
|
+
assert.ok(!('error' in result));
|
|
201
|
+
const { agent } = result;
|
|
202
|
+
const tools = agent.frontmatter.tools ?? [];
|
|
203
|
+
// Developer should have file operations
|
|
204
|
+
assert.ok(tools.includes('readFile'), 'Developer should have readFile');
|
|
205
|
+
assert.ok(tools.includes('editFiles'), 'Developer should have editFiles');
|
|
206
|
+
assert.ok(tools.includes('createFile'), 'Developer should have createFile');
|
|
207
|
+
// Developer should have search capabilities
|
|
208
|
+
assert.ok(tools.includes('codebase'), 'Developer should have codebase');
|
|
209
|
+
assert.ok(tools.includes('fileSearch'), 'Developer should have fileSearch');
|
|
210
|
+
assert.ok(tools.includes('textSearch'), 'Developer should have textSearch');
|
|
211
|
+
// Developer should have terminal access
|
|
212
|
+
assert.ok(tools.includes('runInTerminal'), 'Developer should have runInTerminal');
|
|
213
|
+
assert.ok(tools.includes('getTerminalOutput'), 'Developer should have getTerminalOutput');
|
|
214
|
+
// Developer should be able to spawn subagents
|
|
215
|
+
assert.ok(tools.includes('runSubagent'), 'Developer should have runSubagent');
|
|
216
|
+
});
|
|
217
|
+
it('all agents should have tools as arrays', () => {
|
|
218
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
219
|
+
for (const agent of result.agents) {
|
|
220
|
+
if (agent.frontmatter.tools !== undefined) {
|
|
221
|
+
assert.ok(Array.isArray(agent.frontmatter.tools), `${agent.id} tools should be an array`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
it('all agents should have valid model fields', () => {
|
|
226
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
227
|
+
for (const agent of result.agents) {
|
|
228
|
+
// Model should either be undefined or a non-empty string
|
|
229
|
+
if (agent.frontmatter.model !== undefined) {
|
|
230
|
+
assert.strictEqual(typeof agent.frontmatter.model, 'string', `${agent.id} model should be a string`);
|
|
231
|
+
assert.ok(agent.frontmatter.model.length > 0, `${agent.id} model should not be empty if specified`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
it('tester agent should have testing-specific tools', () => {
|
|
236
|
+
const result = loadAgent(join(TEMPLATES_AGENTS_DIR, 'tester.agent.md'));
|
|
237
|
+
assert.ok(!('error' in result));
|
|
238
|
+
const { agent } = result;
|
|
239
|
+
const tools = agent.frontmatter.tools ?? [];
|
|
240
|
+
// Tester should have diagnostic tools
|
|
241
|
+
assert.ok(tools.includes('problems'), 'Tester should have problems tool');
|
|
242
|
+
// Tester may have testing-specific tools (custom)
|
|
243
|
+
// testFailure and runTests are custom tools used by tester
|
|
244
|
+
});
|
|
245
|
+
it('security-reviewer should have code analysis tools', () => {
|
|
246
|
+
const result = loadAgent(join(TEMPLATES_AGENTS_DIR, 'security-reviewer.agent.md'));
|
|
247
|
+
assert.ok(!('error' in result));
|
|
248
|
+
const { agent } = result;
|
|
249
|
+
const tools = agent.frontmatter.tools ?? [];
|
|
250
|
+
// Security reviewer should have code reading/searching
|
|
251
|
+
assert.ok(tools.includes('codebase'), 'Security reviewer should have codebase');
|
|
252
|
+
assert.ok(tools.includes('readFile'), 'Security reviewer should have readFile');
|
|
253
|
+
assert.ok(tools.includes('textSearch'), 'Security reviewer should have textSearch');
|
|
254
|
+
assert.ok(tools.includes('usages'), 'Security reviewer should have usages for tracking code usage');
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
describe('runSubagent capability validation', () => {
|
|
258
|
+
it('agents with runSubagent tool should have infer: true', () => {
|
|
259
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
260
|
+
for (const agent of result.agents) {
|
|
261
|
+
const tools = agent.frontmatter.tools ?? [];
|
|
262
|
+
const hasRunSubagent = tools.includes('runSubagent');
|
|
263
|
+
const hasInfer = agent.frontmatter.infer === true;
|
|
264
|
+
if (hasRunSubagent) {
|
|
265
|
+
// An agent with runSubagent should either:
|
|
266
|
+
// 1. Have infer: true (can be spawned as subagent itself), OR
|
|
267
|
+
// 2. Have handoffs (can delegate to other agents)
|
|
268
|
+
const hasHandoffs = (agent.frontmatter.handoffs?.length ?? 0) > 0;
|
|
269
|
+
assert.ok(hasInfer || hasHandoffs, `${agent.id} has runSubagent but no infer:true or handoffs - may not be able to participate in multi-agent workflows`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
it('Beth agent should be able to orchestrate all other agents', () => {
|
|
274
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
275
|
+
const beth = result.agents.find((a) => a.id === 'beth');
|
|
276
|
+
assert.ok(beth, 'Beth agent should exist');
|
|
277
|
+
assert.ok(beth?.frontmatter.infer === true, 'Beth should be inferable');
|
|
278
|
+
// Beth should have handoffs to all specialist agents
|
|
279
|
+
const handoffs = beth?.frontmatter.handoffs ?? [];
|
|
280
|
+
const handoffAgents = handoffs.map((h) => h.agent);
|
|
281
|
+
// Beth should be able to hand off to key specialists
|
|
282
|
+
assert.ok(handoffAgents.includes('developer'), 'Beth should have developer handoff');
|
|
283
|
+
assert.ok(handoffAgents.includes('tester'), 'Beth should have tester handoff');
|
|
284
|
+
assert.ok(handoffAgents.includes('ux-designer'), 'Beth should have ux-designer handoff');
|
|
285
|
+
assert.ok(handoffAgents.includes('product-manager'), 'Beth should have product-manager handoff');
|
|
286
|
+
assert.ok(handoffAgents.includes('researcher'), 'Beth should have researcher handoff');
|
|
287
|
+
assert.ok(handoffAgents.includes('security-reviewer'), 'Beth should have security-reviewer handoff');
|
|
288
|
+
});
|
|
289
|
+
it('all inferable agents can be spawned as subagents', () => {
|
|
290
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
291
|
+
const inferableAgents = result.agents.filter((a) => a.frontmatter.infer === true);
|
|
292
|
+
assert.ok(inferableAgents.length > 0, 'Should have at least one inferable agent');
|
|
293
|
+
// All inferable agents should have a name (required for subagent invocation)
|
|
294
|
+
for (const agent of inferableAgents) {
|
|
295
|
+
assert.ok(agent.frontmatter.name, `${agent.id} should have a name for subagent invocation`);
|
|
296
|
+
assert.strictEqual(typeof agent.frontmatter.name, 'string', `${agent.id} name should be a string`);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
it('agents with handoffs should reference valid agent names', () => {
|
|
300
|
+
const result = loadAgents(TEMPLATES_AGENTS_DIR);
|
|
301
|
+
const agentIds = result.agents.map((a) => a.id);
|
|
302
|
+
for (const agent of result.agents) {
|
|
303
|
+
const handoffs = agent.frontmatter.handoffs ?? [];
|
|
304
|
+
for (const handoff of handoffs) {
|
|
305
|
+
assert.ok(agentIds.includes(handoff.agent), `${agent.id} has handoff to unknown agent: ${handoff.agent}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
describe('Known tools completeness', () => {
|
|
311
|
+
it('should include all 12 known tools', () => {
|
|
312
|
+
assert.strictEqual(KNOWN_TOOLS.length, 12);
|
|
313
|
+
// Verify each known tool
|
|
314
|
+
assert.ok(KNOWN_TOOLS.includes('codebase'));
|
|
315
|
+
assert.ok(KNOWN_TOOLS.includes('readFile'));
|
|
316
|
+
assert.ok(KNOWN_TOOLS.includes('editFiles'));
|
|
317
|
+
assert.ok(KNOWN_TOOLS.includes('createFile'));
|
|
318
|
+
assert.ok(KNOWN_TOOLS.includes('listDirectory'));
|
|
319
|
+
assert.ok(KNOWN_TOOLS.includes('fileSearch'));
|
|
320
|
+
assert.ok(KNOWN_TOOLS.includes('textSearch'));
|
|
321
|
+
assert.ok(KNOWN_TOOLS.includes('runInTerminal'));
|
|
322
|
+
assert.ok(KNOWN_TOOLS.includes('getTerminalOutput'));
|
|
323
|
+
assert.ok(KNOWN_TOOLS.includes('problems'));
|
|
324
|
+
assert.ok(KNOWN_TOOLS.includes('usages'));
|
|
325
|
+
assert.ok(KNOWN_TOOLS.includes('runSubagent'));
|
|
326
|
+
});
|
|
327
|
+
it('known tools should have no duplicates', () => {
|
|
328
|
+
const uniqueTools = new Set(KNOWN_TOOLS);
|
|
329
|
+
assert.strictEqual(uniqueTools.size, KNOWN_TOOLS.length, 'KNOWN_TOOLS should have no duplicates');
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
//# sourceMappingURL=tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../../src/core/agents/tools.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation Context Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages conversation state for agent interactions:
|
|
5
|
+
* - Message history with role tracking
|
|
6
|
+
* - Context window management (token estimation + truncation)
|
|
7
|
+
* - System prompt construction from agent definitions + skills
|
|
8
|
+
* - Skill injection when trigger phrases match user input
|
|
9
|
+
*
|
|
10
|
+
* Each agent session gets its own ConversationContext. When handoffs occur,
|
|
11
|
+
* a summary can be extracted and injected into the new agent's context.
|
|
12
|
+
*/
|
|
13
|
+
import type { ChatMessage } from '../providers/types.js';
|
|
14
|
+
import type { AgentDefinition } from './agents/types.js';
|
|
15
|
+
import type { SkillDefinition } from './skills/types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Options for creating a ConversationContext.
|
|
18
|
+
*/
|
|
19
|
+
export interface ConversationContextOptions {
|
|
20
|
+
/** Maximum tokens for the context window (default: 128000) */
|
|
21
|
+
maxTokens?: number;
|
|
22
|
+
/** Tokens reserved for the model's response (default: 4096) */
|
|
23
|
+
responseReserve?: number;
|
|
24
|
+
/** Initial conversation history to restore (e.g., from a handoff) */
|
|
25
|
+
initialMessages?: ChatMessage[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Summary of a conversation for handoff purposes.
|
|
29
|
+
*/
|
|
30
|
+
export interface ConversationSummary {
|
|
31
|
+
/** The agent that was running this conversation */
|
|
32
|
+
agentId: string;
|
|
33
|
+
/** Key points from the conversation */
|
|
34
|
+
summary: string;
|
|
35
|
+
/** Number of turns in the original conversation */
|
|
36
|
+
turnCount: number;
|
|
37
|
+
/** Any tool calls that were made */
|
|
38
|
+
toolCallSummary: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Manages conversation state for a single agent session.
|
|
42
|
+
*
|
|
43
|
+
* Handles message accumulation, context window enforcement,
|
|
44
|
+
* and system prompt construction from agent definitions and skills.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const ctx = new ConversationContext(developerAgent);
|
|
49
|
+
* ctx.addUserMessage('Implement the login page');
|
|
50
|
+
*
|
|
51
|
+
* const messages = ctx.getMessages(); // system + user message
|
|
52
|
+
* // Send to LLM...
|
|
53
|
+
*
|
|
54
|
+
* ctx.addAssistantMessage('I\'ll create the login component...');
|
|
55
|
+
* ctx.addAssistantToolCalls([{ id: '1', type: 'function', function: { name: 'editFile', arguments: '...' } }]);
|
|
56
|
+
* ctx.addToolResult('1', 'File updated successfully');
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare class ConversationContext {
|
|
60
|
+
/** The agent this context belongs to */
|
|
61
|
+
private readonly agent;
|
|
62
|
+
/** Conversation messages (excluding system prompt; it's built dynamically) */
|
|
63
|
+
private messages;
|
|
64
|
+
/** Skills injected into this context */
|
|
65
|
+
private injectedSkills;
|
|
66
|
+
/** Skill content appended to system prompt */
|
|
67
|
+
private skillContent;
|
|
68
|
+
/** Context window configuration */
|
|
69
|
+
private readonly maxTokens;
|
|
70
|
+
private readonly responseReserve;
|
|
71
|
+
/** Custom context additions (handoff summaries, etc.) */
|
|
72
|
+
private additionalContext;
|
|
73
|
+
constructor(agent: AgentDefinition, options?: ConversationContextOptions);
|
|
74
|
+
/**
|
|
75
|
+
* Add a user message to the conversation.
|
|
76
|
+
*/
|
|
77
|
+
addUserMessage(content: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Add an assistant text response to the conversation.
|
|
80
|
+
*/
|
|
81
|
+
addAssistantMessage(content: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* Add an assistant message with tool calls.
|
|
84
|
+
*/
|
|
85
|
+
addAssistantToolCalls(toolCalls: ChatMessage['tool_calls'], content?: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Add a tool result message.
|
|
88
|
+
*/
|
|
89
|
+
addToolResult(toolCallId: string, result: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Get the full message array for sending to the LLM.
|
|
92
|
+
* Includes the constructed system prompt as the first message.
|
|
93
|
+
* Applies truncation if context window is exceeded.
|
|
94
|
+
*/
|
|
95
|
+
getMessages(): ChatMessage[];
|
|
96
|
+
/**
|
|
97
|
+
* Get just the conversation messages (without system prompt).
|
|
98
|
+
*/
|
|
99
|
+
getRawMessages(): ChatMessage[];
|
|
100
|
+
/**
|
|
101
|
+
* Get the number of conversation turns (user messages).
|
|
102
|
+
*/
|
|
103
|
+
getTurnCount(): number;
|
|
104
|
+
/**
|
|
105
|
+
* Get estimated token count for the current context.
|
|
106
|
+
*/
|
|
107
|
+
getEstimatedTokens(): number;
|
|
108
|
+
/**
|
|
109
|
+
* Clear the conversation history, keeping injected skills.
|
|
110
|
+
*/
|
|
111
|
+
clearHistory(): void;
|
|
112
|
+
/**
|
|
113
|
+
* Inject a skill's content into the system prompt.
|
|
114
|
+
* Each skill is only injected once per context.
|
|
115
|
+
*
|
|
116
|
+
* @param skill - The skill to inject
|
|
117
|
+
* @returns true if the skill was injected, false if already present
|
|
118
|
+
*/
|
|
119
|
+
injectSkill(skill: SkillDefinition): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Check if a skill has been injected.
|
|
122
|
+
*/
|
|
123
|
+
hasSkill(skillId: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Get the IDs of all injected skills.
|
|
126
|
+
*/
|
|
127
|
+
getInjectedSkillIds(): string[];
|
|
128
|
+
/**
|
|
129
|
+
* Add additional context (e.g., handoff summary from previous agent).
|
|
130
|
+
*/
|
|
131
|
+
addContext(context: string): void;
|
|
132
|
+
/**
|
|
133
|
+
* Generate a summary of this conversation for handoff purposes.
|
|
134
|
+
*/
|
|
135
|
+
getSummary(): ConversationSummary;
|
|
136
|
+
/**
|
|
137
|
+
* Get the agent definition this context belongs to.
|
|
138
|
+
*/
|
|
139
|
+
getAgent(): AgentDefinition;
|
|
140
|
+
/**
|
|
141
|
+
* Build the full system prompt from the agent definition + injected content.
|
|
142
|
+
*/
|
|
143
|
+
buildSystemPrompt(): string;
|
|
144
|
+
/**
|
|
145
|
+
* Estimate token count for a string.
|
|
146
|
+
*/
|
|
147
|
+
private estimateTokens;
|
|
148
|
+
/**
|
|
149
|
+
* Estimate token count for a single message including structure overhead.
|
|
150
|
+
*/
|
|
151
|
+
private estimateMessageTokens;
|
|
152
|
+
/**
|
|
153
|
+
* Truncate messages to fit within the token budget.
|
|
154
|
+
*
|
|
155
|
+
* Strategy: Keep the most recent messages. Drop oldest messages first,
|
|
156
|
+
* but never drop tool results that are paired with a tool call in the
|
|
157
|
+
* retained messages (to avoid orphaned tool call references).
|
|
158
|
+
*
|
|
159
|
+
* @param messages - Messages to truncate
|
|
160
|
+
* @param maxTokens - Maximum tokens available
|
|
161
|
+
* @returns Truncated message array
|
|
162
|
+
*/
|
|
163
|
+
private truncateMessages;
|
|
164
|
+
/**
|
|
165
|
+
* Remove orphaned tool results (where the corresponding assistant
|
|
166
|
+
* tool_calls message was truncated) and orphaned tool calls
|
|
167
|
+
* (where the results were truncated).
|
|
168
|
+
*/
|
|
169
|
+
private repairToolCallConsistency;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAmBzD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,qEAAqE;IACrE,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAEhB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAEhB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAElB,oCAAoC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,mBAAmB;IAC9B,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IAExC,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAqB;IAErC,wCAAwC;IACxC,OAAO,CAAC,cAAc,CAA0B;IAEhD,8CAA8C;IAC9C,OAAO,CAAC,YAAY,CAAgB;IAEpC,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,yDAAyD;IACzD,OAAO,CAAC,iBAAiB,CAAgB;gBAE7B,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAcxE;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1C;;OAEG;IACH,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAQnF;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvD;;;;OAIG;IACH,WAAW,IAAI,WAAW,EAAE;IAY5B;;OAEG;IACH,cAAc,IAAI,WAAW,EAAE;IAI/B;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAU5B;;OAEG;IACH,YAAY,IAAI,IAAI;IAQpB;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAY5C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAQ/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQjC;;OAEG;IACH,UAAU,IAAI,mBAAmB;IA4BjC;;OAEG;IACH,QAAQ,IAAI,eAAe;IAQ3B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IA0B3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IA6CxB;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;CAgClC"}
|