Skip to content

Commit 8034890

Browse files
authored
Merge pull request #206 from vxcontrol/feature/next_release
Agent Supervision System and Open Source Model Enhancements
2 parents 9be4af4 + df92de1 commit 8034890

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+6871
-1588
lines changed

.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ ASSISTANT_SUMMARIZER_MAX_QA_SECTIONS=
9494
ASSISTANT_SUMMARIZER_MAX_QA_BYTES=
9595
ASSISTANT_SUMMARIZER_KEEP_QA_SECTIONS=
9696

97+
## Execution Monitor Detector
98+
EXECUTION_MONITOR_ENABLED=
99+
EXECUTION_MONITOR_SAME_TOOL_LIMIT=
100+
EXECUTION_MONITOR_TOTAL_TOOL_LIMIT=
101+
102+
## Agent execution tool calls limit
103+
MAX_GENERAL_AGENT_TOOL_CALLS=
104+
MAX_LIMITED_AGENT_TOOL_CALLS=
105+
106+
## Agent planning step for pentester, coder, installer
107+
AGENT_PLANNING_STEP_ENABLED=
108+
97109
## HTTP proxy to use it in isolation environment
98110
PROXY_URL=
99111

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
// "-report", "${workspaceFolder}/examples/tests/ollama-llama318b-instruct-report.md",
8787
// "-report", "${workspaceFolder}/examples/tests/ollama-qwq-32b-fp16-tc-report.md",
8888
// "-report", "${workspaceFolder}/examples/tests/ollama-qwen332b-fp16-tc-report.md",
89-
// "-report", "${workspaceFolder}/examples/tests/vllm-qwen3.5-27b-fp8.provider.md",
89+
// "-report", "${workspaceFolder}/examples/tests/vllm-qwen3.5-27b-fp8.report.md",
9090
// "-report", "${workspaceFolder}/examples/tests/vllm-qwen332b-fp16-report.md",
9191
"-report", "${workspaceFolder}/examples/tests/moonshot-report.md",
9292
// "-report", "${workspaceFolder}/examples/tests/deepseek-report.md",

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ COPY examples/configs/ollama-qwq32b-fp16-tc.provider.yml /opt/pentagi/conf/
139139
COPY examples/configs/openrouter.provider.yml /opt/pentagi/conf/
140140
COPY examples/configs/novita.provider.yml /opt/pentagi/conf/
141141
COPY examples/configs/vllm-qwen3.5-27b-fp8.provider.yml /opt/pentagi/conf/
142+
COPY examples/configs/vllm-qwen3.5-27b-fp8-no-think.provider.yml /opt/pentagi/conf/
142143
COPY examples/configs/vllm-qwen332b-fp16.provider.yml /opt/pentagi/conf/
143144

144145
COPY LICENSE /opt/pentagi/LICENSE

README.md

Lines changed: 101 additions & 22 deletions
Large diffs are not rendered by default.

backend/cmd/ftester/mocks/tools.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,10 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
346346
}
347347

348348
terminal.PrintMock("Search in memory:")
349-
terminal.PrintKeyValue("Question", searchMemoryArgs.Question)
349+
terminal.PrintKeyValueFormat("Questions count", "%d", len(searchMemoryArgs.Questions))
350+
for i, q := range searchMemoryArgs.Questions {
351+
terminal.PrintKeyValueFormat(fmt.Sprintf("Question %d", i+1), "%s", q)
352+
}
350353

351354
if searchMemoryArgs.TaskID != nil {
352355
terminal.PrintKeyValueFormat("Task ID filter", "%d", searchMemoryArgs.TaskID.Int64())
@@ -355,6 +358,8 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
355358
terminal.PrintKeyValueFormat("Subtask ID filter", "%d", searchMemoryArgs.SubtaskID.Int64())
356359
}
357360

361+
questionsText := strings.Join(searchMemoryArgs.Questions, " | ")
362+
358363
var builder strings.Builder
359364
builder.WriteString("# Match score 0.92\n\n")
360365
if searchMemoryArgs.TaskID != nil {
@@ -366,12 +371,12 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
366371
builder.WriteString("# Tool Name 'terminal'\n\n")
367372
builder.WriteString("# Tool Description\n\nCalls a terminal command in blocking mode with hard limit timeout 1200 seconds and optimum timeout 60 seconds\n\n")
368373
builder.WriteString("# Chunk\n\n")
369-
builder.WriteString(fmt.Sprintf("This is a memory chunk related to your question '%s'. It contains information about previous commands, outputs, and relevant context that was stored in the vector database.\n\n", searchMemoryArgs.Question))
374+
builder.WriteString(fmt.Sprintf("This is a memory chunk related to your questions '%s'. It contains information about previous commands, outputs, and relevant context that was stored in the vector database.\n\n", questionsText))
370375
builder.WriteString("---------------------------\n")
371376
builder.WriteString("# Match score 0.85\n\n")
372377
builder.WriteString("# Tool Name 'file'\n\n")
373378
builder.WriteString("# Chunk\n\n")
374-
builder.WriteString("This is another memory chunk that provides additional context to your question. It contains information about file operations and relevant content changes.\n")
379+
builder.WriteString("This is another memory chunk that provides additional context to your questions. It contains information about file operations and relevant content changes.\n")
375380
builder.WriteString("---------------------------\n")
376381

377382
resultObj = builder.String()
@@ -383,15 +388,20 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
383388
}
384389

385390
terminal.PrintMock("Search guide:")
386-
terminal.PrintKeyValue("Question", searchGuideArgs.Question)
391+
terminal.PrintKeyValueFormat("Questions count", "%d", len(searchGuideArgs.Questions))
392+
for i, q := range searchGuideArgs.Questions {
393+
terminal.PrintKeyValueFormat(fmt.Sprintf("Question %d", i+1), "%s", q)
394+
}
387395
terminal.PrintKeyValue("Guide type", searchGuideArgs.Type)
388396

397+
questionsText := strings.Join(searchGuideArgs.Questions, " | ")
398+
389399
if searchGuideArgs.Type == "pentest" {
390-
resultObj = fmt.Sprintf("# Original Guide Type: pentest\n\n# Original Guide Question\n\n%s\n\n## Penetration Testing Guide\n\nThis guide provides a step-by-step approach for conducting a penetration test on the target system.\n\n### 1. Reconnaissance\n- Gather information about the target using OSINT tools\n- Identify potential entry points and attack surfaces\n\n### 2. Scanning\n- Use tools like Nmap to scan for open ports and services\n- Identify vulnerabilities using automated scanners\n\n### 3. Exploitation\n- Attempt to exploit identified vulnerabilities\n- Document successful attack vectors\n\n### 4. Post-Exploitation\n- Maintain access and explore the system\n- Identify sensitive data and potential lateral movement paths\n\n### 5. Reporting\n- Document all findings with proof of concept\n- Provide remediation recommendations\n\n", searchGuideArgs.Question)
400+
resultObj = fmt.Sprintf("# Original Guide Type: pentest\n\n# Original Guide Questions\n\n%s\n\n## Penetration Testing Guide\n\nThis guide provides a step-by-step approach for conducting a penetration test on the target system.\n\n### 1. Reconnaissance\n- Gather information about the target using OSINT tools\n- Identify potential entry points and attack surfaces\n\n### 2. Scanning\n- Use tools like Nmap to scan for open ports and services\n- Identify vulnerabilities using automated scanners\n\n### 3. Exploitation\n- Attempt to exploit identified vulnerabilities\n- Document successful attack vectors\n\n### 4. Post-Exploitation\n- Maintain access and explore the system\n- Identify sensitive data and potential lateral movement paths\n\n### 5. Reporting\n- Document all findings with proof of concept\n- Provide remediation recommendations\n\n", questionsText)
391401
} else if searchGuideArgs.Type == "install" {
392-
resultObj = fmt.Sprintf("# Original Guide Type: install\n\n# Original Guide Question\n\n%s\n\n## Installation Guide\n\n### Prerequisites\n- Operating System: Linux/macOS/Windows\n- Required dependencies: [list]\n\n### Installation Steps\n1. Download the software from the official repository\n ```bash\n git clone https://github.com/example/software.git\n ```\n\n2. Navigate to the project directory\n ```bash\n cd software\n ```\n\n3. Install dependencies\n ```bash\n npm install\n ```\n\n4. Build the project\n ```bash\n npm run build\n ```\n\n5. Verify installation\n ```bash\n npm test\n ```\n\n### Troubleshooting\n- Common issue 1: [solution]\n- Common issue 2: [solution]\n\n", searchGuideArgs.Question)
402+
resultObj = fmt.Sprintf("# Original Guide Type: install\n\n# Original Guide Questions\n\n%s\n\n## Installation Guide\n\n### Prerequisites\n- Operating System: Linux/macOS/Windows\n- Required dependencies: [list]\n\n### Installation Steps\n1. Download the software from the official repository\n ```bash\n git clone https://github.com/example/software.git\n ```\n\n2. Navigate to the project directory\n ```bash\n cd software\n ```\n\n3. Install dependencies\n ```bash\n npm install\n ```\n\n4. Build the project\n ```bash\n npm run build\n ```\n\n5. Verify installation\n ```bash\n npm test\n ```\n\n### Troubleshooting\n- Common issue 1: [solution]\n- Common issue 2: [solution]\n\n", questionsText)
393403
} else {
394-
resultObj = fmt.Sprintf("# Original Guide Type: %s\n\n# Original Guide Question\n\n%s\n\n## Guide Content\n\nThis is a comprehensive guide for the requested type '%s'. It contains detailed instructions, best practices, and examples tailored to your specific question.\n\n### Section 1: Getting Started\n[Detailed content would be here]\n\n### Section 2: Main Procedures\n[Step-by-step instructions would be here]\n\n### Section 3: Advanced Techniques\n[Advanced content would be here]\n\n### Section 4: Troubleshooting\n[Common issues and solutions would be here]\n\n", searchGuideArgs.Type, searchGuideArgs.Question, searchGuideArgs.Type)
404+
resultObj = fmt.Sprintf("# Original Guide Type: %s\n\n# Original Guide Questions\n\n%s\n\n## Guide Content\n\nThis is a comprehensive guide for the requested type '%s'. It contains detailed instructions, best practices, and examples tailored to your specific questions.\n\n### Section 1: Getting Started\n[Detailed content would be here]\n\n### Section 2: Main Procedures\n[Step-by-step instructions would be here]\n\n### Section 3: Advanced Techniques\n[Advanced content would be here]\n\n### Section 4: Troubleshooting\n[Common issues and solutions would be here]\n\n", searchGuideArgs.Type, questionsText, searchGuideArgs.Type)
395405
}
396406

397407
case tools.StoreGuideToolName:
@@ -414,13 +424,18 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
414424
}
415425

416426
terminal.PrintMock("Search answer:")
417-
terminal.PrintKeyValue("Question", searchAnswerArgs.Question)
427+
terminal.PrintKeyValueFormat("Questions count", "%d", len(searchAnswerArgs.Questions))
428+
for i, q := range searchAnswerArgs.Questions {
429+
terminal.PrintKeyValueFormat(fmt.Sprintf("Question %d", i+1), "%s", q)
430+
}
418431
terminal.PrintKeyValue("Answer type", searchAnswerArgs.Type)
419432

433+
questionsText := strings.Join(searchAnswerArgs.Questions, " | ")
434+
420435
if searchAnswerArgs.Type == "vulnerability" {
421-
resultObj = fmt.Sprintf("# Original Answer Type: vulnerability\n\n# Original Search Question\n\n%s\n\n## Vulnerability Details\n\n### CVE-2023-12345\n\n**Severity**: High\n\n**Affected Systems**: Linux servers running Apache 2.4.x before 2.4.56\n\n**Description**:\nA buffer overflow vulnerability in Apache HTTP Server allows attackers to execute arbitrary code via a crafted request.\n\n**Exploitation**:\nAttackers can send a specially crafted HTTP request that triggers the buffer overflow, leading to remote code execution with the privileges of the web server process.\n\n**Remediation**:\n- Update Apache HTTP Server to version 2.4.56 or later\n- Apply the security patch provided by the vendor\n- Implement network filtering to block malicious requests\n\n**References**:\n- https://example.com/cve-2023-12345\n- https://example.com/apache-advisory\n", searchAnswerArgs.Question)
436+
resultObj = fmt.Sprintf("# Original Answer Type: vulnerability\n\n# Original Search Questions\n\n%s\n\n## Vulnerability Details\n\n### CVE-2023-12345\n\n**Severity**: High\n\n**Affected Systems**: Linux servers running Apache 2.4.x before 2.4.56\n\n**Description**:\nA buffer overflow vulnerability in Apache HTTP Server allows attackers to execute arbitrary code via a crafted request.\n\n**Exploitation**:\nAttackers can send a specially crafted HTTP request that triggers the buffer overflow, leading to remote code execution with the privileges of the web server process.\n\n**Remediation**:\n- Update Apache HTTP Server to version 2.4.56 or later\n- Apply the security patch provided by the vendor\n- Implement network filtering to block malicious requests\n\n**References**:\n- https://example.com/cve-2023-12345\n- https://example.com/apache-advisory\n", questionsText)
422437
} else {
423-
resultObj = fmt.Sprintf("# Original Answer Type: %s\n\n# Original Search Question\n\n%s\n\n## Comprehensive Answer\n\nThis is a detailed answer to your question related to the type '%s'. The answer provides comprehensive information, examples, and best practices.\n\n### Key Points\n1. First important point about your question\n2. Second important aspect to consider\n3. Technical details relevant to your inquiry\n\n### Examples\n```\nExample code or configuration would be here\n```\n\n### Additional Resources\n- Resource 1: [description]\n- Resource 2: [description]\n\n", searchAnswerArgs.Type, searchAnswerArgs.Question, searchAnswerArgs.Type)
438+
resultObj = fmt.Sprintf("# Original Answer Type: %s\n\n# Original Search Questions\n\n%s\n\n## Comprehensive Answer\n\nThis is a detailed answer to your questions related to the type '%s'. The answer provides comprehensive information, examples, and best practices.\n\n### Key Points\n1. First important point about your questions\n2. Second important aspect to consider\n3. Technical details relevant to your inquiry\n\n### Examples\n```\nExample code or configuration would be here\n```\n\n### Additional Resources\n- Resource 1: [description]\n- Resource 2: [description]\n\n", searchAnswerArgs.Type, questionsText, searchAnswerArgs.Type)
424439
}
425440

426441
case tools.StoreAnswerToolName:
@@ -443,9 +458,14 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
443458
}
444459

445460
terminal.PrintMock("Search code:")
446-
terminal.PrintKeyValue("Question", searchCodeArgs.Question)
461+
terminal.PrintKeyValueFormat("Questions count", "%d", len(searchCodeArgs.Questions))
462+
for i, q := range searchCodeArgs.Questions {
463+
terminal.PrintKeyValueFormat(fmt.Sprintf("Question %d", i+1), "%s", q)
464+
}
447465
terminal.PrintKeyValue("Language", searchCodeArgs.Lang)
448466

467+
questionsText := strings.Join(searchCodeArgs.Questions, " | ")
468+
449469
var mockCode string
450470
if searchCodeArgs.Lang == "python" {
451471
mockCode = "def example_function(param1, param2='default'):\n \"\"\"This is an example Python function that demonstrates a pattern.\n \n Args:\n param1: The first parameter\n param2: The second parameter with default value\n \n Returns:\n The processed result\n \"\"\"\n result = {}\n \n # Process the parameters\n if param1 is not None:\n result['param1'] = param1\n \n # Additional processing\n if param2 != 'default':\n result['param2'] = param2\n \n return result\n\n# Example usage\nif __name__ == '__main__':\n output = example_function('test', 'custom')\n print(output)"
@@ -455,7 +475,7 @@ func MockResponse(funcName string, args json.RawMessage) (string, error) {
455475
mockCode = fmt.Sprintf("// Example code in %s language\n// This is a mock code snippet that would be returned from the vector database\n\n// Main function definition\nfunction exampleFunction(param) {\n // Initialization\n const result = [];\n \n // Processing logic\n for (let i = 0; i < param.length; i++) {\n result.push(processItem(param[i]));\n }\n \n return result;\n}\n\n// Helper function\nfunction processItem(item) {\n return item.transform();\n}", searchCodeArgs.Lang)
456476
}
457477

458-
resultObj = fmt.Sprintf("# Original Code Question\n\n%s\n\n# Original Code Description\n\nThis code sample demonstrates the implementation pattern for handling the specific scenario you asked about. It includes proper error handling, input validation, and follows best practices for %s.\n\n```%s\n%s\n```\n\n", searchCodeArgs.Question, searchCodeArgs.Lang, searchCodeArgs.Lang, mockCode)
478+
resultObj = fmt.Sprintf("# Original Code Questions\n\n%s\n\n# Original Code Description\n\nThis code sample demonstrates the implementation pattern for handling the specific scenarios you asked about. It includes proper error handling, input validation, and follows best practices for %s.\n\n```%s\n%s\n```\n\n", questionsText, searchCodeArgs.Lang, searchCodeArgs.Lang, mockCode)
459479

460480
case tools.StoreCodeToolName:
461481
var storeCodeArgs tools.StoreCodeAction

backend/cmd/ftester/worker/executor.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
"pentagi/pkg/tools"
1717

1818
"github.com/sirupsen/logrus"
19+
"github.com/vxcontrol/cloud/anonymizer"
20+
"github.com/vxcontrol/cloud/anonymizer/patterns"
1921
"github.com/vxcontrol/langchaingo/vectorstores/pgvector"
2022
)
2123

@@ -37,6 +39,7 @@ func (at *agentTool) IsAvailable() bool {
3739
// toolExecutor holds the necessary data for creating and managing tools
3840
type toolExecutor struct {
3941
flowExecutor tools.FlowToolsExecutor
42+
replacer anonymizer.Replacer
4043
cfg *config.Config
4144
db database.Querier
4245
dockerClient docker.DockerClient
@@ -61,7 +64,7 @@ func newToolExecutor(
6164
taskID, subtaskID *int64,
6265
embedder embeddings.Embedder,
6366
graphitiClient *graphiti.Client,
64-
) *toolExecutor {
67+
) (*toolExecutor, error) {
6568
var store *pgvector.Store
6669
if embedder.IsAvailable() {
6770
s, err := pgvector.New(
@@ -76,8 +79,22 @@ func newToolExecutor(
7679
}
7780
}
7881

82+
allPatterns, err := patterns.LoadPatterns(patterns.PatternListTypeAll)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to load all patterns: %v", err)
85+
}
86+
87+
// combine with config secret patterns
88+
allPatterns.Patterns = append(allPatterns.Patterns, cfg.GetSecretPatterns()...)
89+
90+
replacer, err := anonymizer.NewReplacer(allPatterns.Regexes(), allPatterns.Names())
91+
if err != nil {
92+
return nil, fmt.Errorf("failed to create replacer: %v", err)
93+
}
94+
7995
return &toolExecutor{
8096
flowExecutor: flowExecutor,
97+
replacer: replacer,
8198
cfg: cfg,
8299
db: db,
83100
dockerClient: dockerClient,
@@ -88,7 +105,7 @@ func newToolExecutor(
88105
flowID: flowID,
89106
taskID: taskID,
90107
subtaskID: subtaskID,
91-
}
108+
}, nil
92109
}
93110

94111
// GetTool returns the appropriate tool for a given function name
@@ -221,6 +238,7 @@ func (te *toolExecutor) GetTool(ctx context.Context, funcName string) (tools.Too
221238
te.flowID,
222239
te.taskID,
223240
te.subtaskID,
241+
te.replacer,
224242
te.store,
225243
te.proxies.GetVectorStoreLogProvider(),
226244
), nil
@@ -230,6 +248,7 @@ func (te *toolExecutor) GetTool(ctx context.Context, funcName string) (tools.Too
230248
te.flowID,
231249
te.taskID,
232250
te.subtaskID,
251+
te.replacer,
233252
te.store,
234253
te.proxies.GetVectorStoreLogProvider(),
235254
), nil
@@ -239,6 +258,7 @@ func (te *toolExecutor) GetTool(ctx context.Context, funcName string) (tools.Too
239258
te.flowID,
240259
te.taskID,
241260
te.subtaskID,
261+
te.replacer,
242262
te.store,
243263
te.proxies.GetVectorStoreLogProvider(),
244264
), nil

backend/cmd/ftester/worker/tester.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,14 @@ func NewTester(
8484
flowExecutor.SetGraphitiClient(providerController.GraphitiClient())
8585

8686
// Initialize tool executor
87-
toolExecutor := newToolExecutor(
87+
toolExecutor, err := newToolExecutor(
8888
flowExecutor, cfg, db, dockerClient, nil, proxies,
8989
flowID, taskID, subtaskID, providerController.Embedder(),
9090
providerController.GraphitiClient(),
9191
)
92+
if err != nil {
93+
return nil, fmt.Errorf("failed to create tool executor: %w", err)
94+
}
9295

9396
t := &tester{
9497
db: db,

0 commit comments

Comments
 (0)