Skip to content

Commit

Permalink
Merge pull request #89 from meysamhadeli/refactor/refactor-prompt-to-…
Browse files Browse the repository at this point in the history
…get-more-accurate-results

refactor: refactor prompt to get more accurate results
  • Loading branch information
meysamhadeli authored Nov 27, 2024
2 parents 14e021c + 1f14572 commit 195c2df
Show file tree
Hide file tree
Showing 24 changed files with 178 additions and 164 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,33 +121,33 @@ This command will initiate the codai assistant to help you with your coding task

🧠 Context-aware code completions.

Propose new features or test cases.
Adding new features or test cases.

🔄 Improve code structure and efficiency.
🔄 Refactoring code structure and efficiency.

🐛 Diagnose and suggest fixes for bugs.
🐛 Describe and suggest fixes for bugs.

Identify issues and optimize code quality.
Code Review Assistance and optimize code quality.

✔️ Accept and apply AI-generated changes.
✔️ Accept and apply AI-generated code changes.

📚 Generate comprehensive documentation.

🌐 Works with multiple programming languages.
🌐 Works with multiple programming languages such as (C#, Go, Python, Java, Javascript, Typescript).

⚙️ Adjust settings via a config file.

📊 Maintain understanding of the entire project.

🌳 Summarize code context using Tree-sitter.
🔍 Retrieve relevant context for accurate suggestions using RAG.

🔍 Retrieve relevant context for precise suggestions.
🌳 Summarize Full Project Context using Tree-sitter.

Leverage models like GPT-4o, GPT-4, and Ollama.
Support variety of LLM models like GPT-4o, GPT-4, and Ollama.

🗂️ Modify several files simultaneously.
🗂️ Enable the AI to modify several files at the same time.

💳 Track and display API token usage.
💳 Track and represent the token consumption for each request.

## 🗺️ Plan
🌀 This project is a work in progress; new features will be added over time. 🌀
Expand Down
4 changes: 2 additions & 2 deletions providers/chat_history.go → chat_history/chat_history.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package providers
package chat_history

import (
"fmt"
"github.com/meysamhadeli/codai/providers/contracts"
"github.com/meysamhadeli/codai/chat_history/contracts"
"time"
)

Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions cmd/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func handleCodeCommand(rootDependencies *RootDependencies) {

for _, dataFile := range fullContext {
// Split file into chunks of up to 8000 tokens
fileChunks, err := utils.SplitIntoChunks(dataFile.Code, maxTokens)
fileChunks, err := rootDependencies.TokenManagement.SplitTokenIntoChunks(dataFile.Code, maxTokens)
if err != nil {
spinnerEmbeddingContext.Stop()
fmt.Print("\r")
Expand All @@ -121,7 +121,7 @@ func handleCodeCommand(rootDependencies *RootDependencies) {
}

for _, chunk := range fileChunks {
tokenCount, err := utils.TokenCount(chunk)
tokenCount, err := rootDependencies.TokenManagement.TokenCount(chunk)
if err != nil {
spinnerEmbeddingContext.Stop()
fmt.Print("\r")
Expand Down
12 changes: 8 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"fmt"
"github.com/meysamhadeli/codai/chat_history"
contracts2 "github.com/meysamhadeli/codai/chat_history/contracts"
"github.com/meysamhadeli/codai/code_analyzer"
contracts_analyzer "github.com/meysamhadeli/codai/code_analyzer/contracts"
"github.com/meysamhadeli/codai/config"
Expand All @@ -10,6 +12,8 @@ import (
contracts_store "github.com/meysamhadeli/codai/embedding_store/contracts"
"github.com/meysamhadeli/codai/providers"
contracts_provider "github.com/meysamhadeli/codai/providers/contracts"
"github.com/meysamhadeli/codai/token_management"
"github.com/meysamhadeli/codai/token_management/contracts"
"github.com/spf13/cobra"
"os"
)
Expand All @@ -22,8 +26,8 @@ type RootDependencies struct {
Analyzer contracts_analyzer.ICodeAnalyzer
Cwd string
Config *config.Config
ChatHistory contracts_provider.IChatHistory
TokenManagement contracts_provider.ITokenManagement
ChatHistory contracts2.IChatHistory
TokenManagement contracts.ITokenManagement
}

// RootCmd represents the 'context' command
Expand Down Expand Up @@ -59,9 +63,9 @@ func handleRootCommand(cmd *cobra.Command) *RootDependencies {

rootDependencies.Config = config.LoadConfigs(cmd, rootDependencies.Cwd)

rootDependencies.TokenManagement = providers.NewTokenManager()
rootDependencies.TokenManagement = token_management.NewTokenManager()

rootDependencies.ChatHistory = providers.NewChatHistory()
rootDependencies.ChatHistory = chat_history.NewChatHistory()

rootDependencies.Analyzer = code_analyzer.NewCodeAnalyzer(rootDependencies.Cwd, rootDependencies.Config.RAG)

Expand Down
33 changes: 12 additions & 21 deletions code_analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,14 @@ func (analyzer *CodeAnalyzer) ProcessFile(filePath string, sourceCode []byte) []
default:
// If the language doesn't match, process the original source code directly
elements = append(elements, filePath)
elements = append(elements, string(sourceCode)) // Adding original source code
if analyzer.IsRAG {
elements = append(elements, string(sourceCode)) // Adding original source code
} else {
lines := strings.Split(string(sourceCode), "\n")
// Get the first line
elements = append(elements, lines[0]) // Adding First line from the array
}

return elements
}

Expand Down Expand Up @@ -205,26 +212,10 @@ func (analyzer *CodeAnalyzer) ProcessFile(filePath string, sourceCode []byte) []

for _, cap := range match.Captures {
element := cap.Node.Content(sourceCode)
queryName := query.CaptureNameForId(cap.Index)

if !analyzer.IsRAG {
if strings.HasPrefix(queryName, "definition.") {
lines := strings.Split(element, "\n")
// Get the first line
element = lines[0] // First line from the array
} else {
continue
}
taggedElement := fmt.Sprintf("%s:\n %s", tag, element)
elements = append(elements, taggedElement)
} else {
if !strings.HasPrefix(queryName, "definition.") {
taggedElement := fmt.Sprintf("%s:\n %s", tag, element)
elements = append(elements, taggedElement)
}
}
// Tag the element with its type (e.g., namespace, class, method, interface)
taggedElement := fmt.Sprintf("%s: %s", tag, element)
elements = append(elements, taggedElement)
}

}
}

Expand Down Expand Up @@ -386,7 +377,7 @@ func (analyzer *CodeAnalyzer) ApplyChanges(relativePath, diff string) error {
}

// Handle deletion if code is empty
if diff == "" {
if strings.TrimSpace(strings.Join(updatedContent, "\n")) == "" {
// Check if file exists, then delete if it does
if err := os.Remove(relativePath); err != nil {
if os.IsNotExist(err) {
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Config struct {

// Default configuration values
var defaultConfig = Config{
Version: "1.7.4",
Version: "1.7.5",
Theme: "dracula",
RAG: true,
AIProviderConfig: &providers.AIProviderConfig{
Expand Down
23 changes: 13 additions & 10 deletions embed_data/prompts/rag_context_prompt.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,27 @@
- You NEVER leave comments describing code without implementing it!
- You always COMPLETELY IMPLEMENT the needed code!


## General Instructions for Code Modifications:
- **First line**: the **file name** with **relative path**; no extra markup, punctuation, comments, etc. **JUST** the **file name** with **relative path** and **file name** should using **naming conversion** base on **language**.
- **Second line**: Start of the **diff BLOCK**.
- **All subsequent lines**: The modified code, with specific prefixes based on the change:
- Prefix **"+"** for added lines.
- Prefix **"-"** for removed lines.
- Prefix **+** for added lines.
- Prefix **-** for removed lines.
- **Unchanged lines** should **not** be prefixed; they should remain as they are.
- **Last line**: End of the **diff BLOCK**.
- Always add **relative path** and **file name** **top** of each **diff BLOCK**.
- If **add** a new line, always **must** use prefix **"+"**.
- If **remove** a line, always **must** use prefix **"-"**.
- If you **modify** or **fix** or **refactor** each line **must** use **"+"** or **"-"** and for **unchanged line** leave it as it is.
- **Do not** forget put prefix **"+"** and **"-"** during **modification** lines.
- If **add** a new line, always **must** use prefix **+**.
- If **remove** a line, always **must** use prefix **-**.
- If you **modify** or **fix** or **refactor** each line **must** use **+** or **-** and for **unchanged line** leave it as it is.
- **Do not** forget put prefix **+** when you **add some new lines** and prefix **-** when you **remove some lines** in current code base during **modification** .
- **Do not** forget when you **create a new file** put prefix **+** for **all of lines**, because all of these lines are **new** and **must** have prefix **+**.
- **Always** use **diff BLOCK** for representing the code.

## **diff BLOCK** Code Format:
## **diff BLOCK** Format:

File: relativePath/fileName.ext
```if chane is a modification use **diff**, otherwise if it's a **new file** use **language of code** here.
```diff
package main

import "fmt"
Expand All @@ -42,8 +45,8 @@ File: relativePath/fileName.ext
```

## Explanation:
- No introduction needed.
- Explain any needed changes in code.
- No introduction needed.
- Explain any needed changes in code.


## Important:
Expand Down
70 changes: 40 additions & 30 deletions embed_data/prompts/summarize_full_context_prompt.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,34 @@

> Your tasks are according to these steps:

## PRIORITY: Check for Specific Context in Code
- **If I request the **specific context of code**, such as a **method**, **class**, or any **part of codes** that is an **empty body** or **incomplete** code, I will provide **full file of code** in the **next request** and base on that you can do your task and you **must** follow these steps:**
- **These examples of context of code are incomplete**:
```go
function AddProduct(){
}
```
```go
function DeleteProduct(){
```
```go
struct: Product
```
```go
class: Product
```

- **I you see the incomplete code like above example just return the relative paths of the relevant files that are incomplete as a JSON array of strings in the following format:**
```json
{
"files": ["relative path1", "relative path2"]
}
- **Skip all other tasks and return only this JSON response. Do not proceed to any additional prompt processing.**

## General Instructions for Code Modifications
If the request does not fall under the above condition, proceed with the following steps:


## Context Understanding:
- Read and Analyze the code context carefully to identify where the requested changes should be added or modified.
- If the request is ambiguous, ask clarifying questions.
Expand All @@ -13,44 +41,26 @@
- You always COMPLETELY IMPLEMENT the needed code!


## PRIORITY: Handling Specific Code Context Requests
### Full Code Implementation Provided
- **If the provided code context includes a complete implementation of the requested method, class, or code part:**
- **Proceed with the task as instructed.**
- **Follow all steps for modifying, adding, or refactoring as necessary.**

### Signature-Only or Incomplete Code Context
- **If the provided code context includes only a method, class, function signature, or other structure without a full body, or the body is incomplete:**
- **Do not complete or modify the code.**
- **Return only the relevant file paths in a JSON array as follows:**

```json
{
"files": ["relative path1", "relative path2"]
}
```
- **Skip all further instructions**, including any additional processing or explanation.



## General Instructions for Code Modifications:
- **First line**: the **file name** with **relative path**; no extra markup, punctuation, comments, etc. **JUST** the **file name** with **relative path** and **file name** should using **naming conversion** base on **language**.
- **Second line**: Start of the **diff BLOCK**.
- **All subsequent lines**: The modified code, with specific prefixes based on the change:
- Prefix **"+"** for added lines.
- Prefix **"-"** for removed lines.
- Prefix **+** for added lines.
- Prefix **-** for removed lines.
- **Unchanged lines** should **not** be prefixed; they should remain as they are.
- **Last line**: End of the **diff BLOCK**.
- Always add **relative path** and **file name** **top** of each **diff BLOCK**.
- If **add** a new line, always **must** use prefix **"+"**.
- If **remove** a line, always **must** use prefix **"-"**.
- If you **modify** or **fix** or **refactor** each line **must** use **"+"** or **"-"** and for **unchanged line** leave it as it is.
- **Do not** forget put prefix **"+"** and **"-"** during **modification** lines.
- If **add** a new line, always **must** use prefix **+**.
- If **remove** a line, always **must** use prefix **-**.
- If you **modify** or **fix** or **refactor** each line **must** use **+** or **-** and for **unchanged line** leave it as it is.
- **Do not** forget put prefix **+** when you **add some new lines** and prefix **-** when you **remove some lines** in current code base during **modification** .
- **Do not** forget when you **create a new file** put prefix **+** for **all of lines**, because all of these lines are **new** and **must** have prefix **+**.
- **Always** use **diff BLOCK** for representing the code.

## **diff BLOCK** Code Format:
## **diff BLOCK** Format:

File: relativePath/fileName.ext
```if chane is a modification use **diff**, otherwise if it's a **new file** use **language of code** here.
```diff
package main

import "fmt"
Expand All @@ -65,8 +75,8 @@ File: relativePath/fileName.ext
```

## Explanation:
- No introduction needed.
- Explain any needed changes in code.
- No introduction needed.
- Explain any needed changes in code.


## Important:
Expand Down
18 changes: 9 additions & 9 deletions embed_data/tree-sitter/queries/csharp.scm
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"file_scoped_namespace": "(file_scoped_namespace_declaration name: (identifier)? @name.file_scoped_namespace name: (qualified_name)? @name) @definition.file_scoped_namespace",
"namespace": "(namespace_declaration name: (qualified_name)? @name.namespace name: (identifier)? @name) @definition.namespace",
"class": "(class_declaration name: (identifier) @name) @definition.class",
"interface": "(interface_declaration name: (identifier) @name) @definition.interface",
"method": "(method_declaration name: (identifier) @name) @definition.method",
"enum": "(enum_declaration name: (identifier) @name) @definition.enum",
"struct": "(struct_declaration name: (identifier) @name) @definition.struct",
"record": "(record_declaration name: (identifier) @name) @definition.record",
"property": "(property_declaration name: (identifier) @name) @definition.property"
"file_scoped_namespace": "(file_scoped_namespace_declaration name: (identifier)? @name.file_scoped_namespace name: (qualified_name)? @name)",
"namespace": "(namespace_declaration name: (qualified_name)? @name.namespace name: (identifier)? @name)",
"class": "(class_declaration name: (identifier) @name)",
"interface": "(interface_declaration name: (identifier) @name)",
"method": "(method_declaration name: (identifier) @name)",
"enum": "(enum_declaration name: (identifier) @name)",
"struct": "(struct_declaration name: (identifier) @name)",
"record": "(record_declaration name: (identifier) @name)",
"property": "(property_declaration name: (identifier) @name)"
}
10 changes: 5 additions & 5 deletions embed_data/tree-sitter/queries/go.scm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"package": "(package_clause (package_identifier) @name) @definition.package",
"function": "(function_declaration name: (identifier) @name) @definition.function",
"method": "(method_declaration name: (field_identifier) @name) @definition.method",
"interface": "(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface",
"struct": "(type_declaration (type_spec name: name: (type_identifier) @name type: (struct_type))) @definition.struct"
"package": "(package_clause (package_identifier) @name)",
"function": "(function_declaration name: (identifier) @name)",
"method": "(method_declaration name: (field_identifier) @name)",
"interface": "(type_declaration (type_spec name: (type_identifier) @name type: (interface_type)))",
"struct": "(type_declaration (type_spec name: name: (type_identifier) @name type: (struct_type)))"
}

10 changes: 5 additions & 5 deletions embed_data/tree-sitter/queries/java.scm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"package": "(package_declaration (scoped_identifier name: (identifier) @name)) @definition.package",
"class": "(class_declaration name: (identifier) @name) @definition.class",
"interface": "(interface_declaration name: (identifier) @name) @definition.interface",
"method": "(method_declaration name: (identifier) @name) @definition.method",
"enum": "(enum_declaration name: (identifier) @name) @definition.enum"
"package": "(package_declaration (scoped_identifier name: (identifier) @name))",
"class": "(class_declaration name: (identifier) @name)",
"interface": "(interface_declaration name: (identifier) @name)",
"method": "(method_declaration name: (identifier) @name)",
"enum": "(enum_declaration name: (identifier) @name)"
}
8 changes: 4 additions & 4 deletions embed_data/tree-sitter/queries/javascript.scm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"class" : "(class_declaration name: (identifier) @name) @definition.class",
"method": "(method_definition name: (property_identifier) @name) @definition.method",
"function": "(function_declaration name: (identifier) @name) @definition.function",
"anonymous_function": "(lexical_declaration(variable_declarator name: (identifier) @name)) @definition.anonymous_function"
"class" : "(class_declaration name: (identifier) @name)",
"method": "(method_definition name: (property_identifier) @name)",
"function": "(function_declaration name: (identifier) @name)",
"anonymous_function": "(lexical_declaration(variable_declarator name: (identifier) @name))"
}

6 changes: 3 additions & 3 deletions embed_data/tree-sitter/queries/python.scm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"class": "(class_definition name: (identifier) @name) @definition.class",
"function": "(function_definition name: (identifier) @name) @definition.function",
"decorated" : "(decorated_definition(decorator((identifier) @name))) @definition.decorated"
"class": "(class_definition name: (identifier) @name)",
"function": "(function_definition name: (identifier) @name)",
"decorated" : "(decorated_definition(decorator((identifier) @name)))"
}
Loading

0 comments on commit 195c2df

Please sign in to comment.