cobie 1.0__tar.gz

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.
cobie-1.0/PKG-INFO ADDED
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: cobie
3
+ Version: 1.0
4
+ Summary: Your local AI coding agent
5
+ Author: Xitiz mgr
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: google-genai
9
+ Requires-Dist: rich
10
+ Requires-Dist: python-dotenv
11
+
12
+ # What is COBIE
13
+
14
+ > COBIE is your local ai
15
+ > COBIE is a local AI coding agent that works directly with your project through the terminal.
16
+
17
+ ![alt text](image-1.png)
18
+
19
+ Cobie is powered by gemini api . which u can get it for free in _ https://aistudio.google.com/api-keys _
20
+
21
+ ## Feature
22
+
23
+ - directly run on terminal no need to copy paste and ask llm for fixing u can directly fix it
24
+ - Read file
25
+ - Write file
26
+ - edit file , etc
27
+
28
+ # Tech Stack
29
+
30
+ - python
31
+ - Rich for terminal ui
32
+ - google gemini api key
33
+ - python subprocess module
cobie-1.0/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # What is COBIE
2
+
3
+ > COBIE is your local ai
4
+ > COBIE is a local AI coding agent that works directly with your project through the terminal.
5
+
6
+ ![alt text](image-1.png)
7
+
8
+ Cobie is powered by gemini api . which u can get it for free in _ https://aistudio.google.com/api-keys _
9
+
10
+ ## Feature
11
+
12
+ - directly run on terminal no need to copy paste and ask llm for fixing u can directly fix it
13
+ - Read file
14
+ - Write file
15
+ - edit file , etc
16
+
17
+ # Tech Stack
18
+
19
+ - python
20
+ - Rich for terminal ui
21
+ - google gemini api key
22
+ - python subprocess module
File without changes
@@ -0,0 +1,4 @@
1
+ from cobie.cli.main import run_cli
2
+
3
+ if __name__ == "__main__":
4
+ run_cli()
File without changes
@@ -0,0 +1,217 @@
1
+
2
+ from google import genai
3
+ from google.genai import types
4
+ from cobie.tools.registry import ToolRegister
5
+
6
+ class Agent:
7
+ def __init__(self,api_key):
8
+ self.client = genai.Client(api_key=api_key)
9
+ self.registry = ToolRegister()
10
+ self.contents = []
11
+ # you can change the gemini model as u want
12
+ self.model = "gemini-3-flash-preview"
13
+ self.instructions = """
14
+ You are COBIE, a local AI coding agent.
15
+
16
+ You help the user understand and work with their project.
17
+
18
+ You have access to tools that can:
19
+
20
+ - read files
21
+ - write files
22
+ - list directories
23
+ - search files
24
+ - run terminal commands
25
+ - inspect git status
26
+ - inspect git diff
27
+ - edit files
28
+
29
+ IMPORTANT RULES:
30
+
31
+ 1. Do NOT use tools for normal conversation.
32
+ 2. Do NOT use tools just because the user says something personal or conversational.
33
+ 3. Only use a tool when the user's request actually requires information or an action involving the project.
34
+ 4. If the user says something like " who am i whats my name", simply respond naturally and do not use any tool.
35
+ 5. Remember information from the current conversation when answering later questions.
36
+ 6. Do not pretend you used a tool when you did not.
37
+ 7. Give clear and concise answers.
38
+ """
39
+
40
+ self.tools = [
41
+ {
42
+ "name": "read_file",
43
+ "description": "Read and return the contents of a file.",
44
+ "parameters": {
45
+ "type": "object",
46
+ "properties": {
47
+ "path": {
48
+ "type": "string",
49
+ "description": "Path to the file to read.",
50
+ }
51
+ },
52
+ "required": ["path"],
53
+ },
54
+ },
55
+ {
56
+ "name": "write_file",
57
+ "description": "Write content to a file.",
58
+ "parameters": {
59
+ "type": "object",
60
+ "properties": {
61
+ "path": {
62
+ "type": "string",
63
+ "description": "Path of the file to write.",
64
+ },
65
+ "content": {
66
+ "type": "string",
67
+ "description": "Content to write to the file.",
68
+ },
69
+ },
70
+ "required": ["path", "content"],
71
+ },
72
+ },
73
+ {
74
+ "name": "list_directory",
75
+ "description": "List files and directories inside a directory.",
76
+ "parameters": {
77
+ "type": "object",
78
+ "properties": {
79
+ "path": {
80
+ "type": "string",
81
+ "description": "Directory path.",
82
+ }
83
+ },
84
+ "required": ["path"],
85
+ },
86
+ },
87
+ {
88
+ "name": "search_file",
89
+ "description": "Search project files for a text query.",
90
+ "parameters": {
91
+ "type": "object",
92
+ "properties": {
93
+ "query": {
94
+ "type": "string",
95
+ "description": "Text to search for.",
96
+ },
97
+ "path": {
98
+ "type": "string",
99
+ "description": "Directory to search in.",
100
+ },
101
+ },
102
+ "required": ["query", "path"],
103
+ },
104
+ },
105
+ {
106
+ "name": "run_command",
107
+ "description": "Run a terminal command.",
108
+ "parameters": {
109
+ "type": "object",
110
+ "properties": {
111
+ "command": {
112
+ "type": "string",
113
+ "description": "Terminal command to execute.",
114
+ }
115
+ },
116
+ "required": ["command"],
117
+ },
118
+ },
119
+ {
120
+ "name": "git_status",
121
+ "description": "Show the current git status.",
122
+ "parameters": {
123
+ "type": "object",
124
+ "properties": {},
125
+ },
126
+ },
127
+ {
128
+ "name": "git_diff",
129
+ "description": "Show the current git diff.",
130
+ "parameters": {
131
+ "type": "object",
132
+ "properties": {},
133
+ },
134
+ },
135
+ {
136
+ "name": "edit_file",
137
+ "description": "Replace a specific piece of text in a file.",
138
+ "parameters": {
139
+ "type": "object",
140
+ "properties": {
141
+ "path": {
142
+ "type": "string",
143
+ "description": "Path to the file.",
144
+ },
145
+ "old_text": {
146
+ "type": "string",
147
+ "description": "Existing text to replace.",
148
+ },
149
+ "new_text": {
150
+ "type": "string",
151
+ "description": "New text.",
152
+ },
153
+ },
154
+ "required": ["path", "old_text", "new_text"],
155
+ },
156
+ },
157
+ ]
158
+
159
+ self.config = types.GenerateContentConfig(
160
+ system_instruction=self.instructions,
161
+ tools=[types.Tool(function_declarations=self.tools)],
162
+ )
163
+
164
+
165
+ def run(self, user_message):
166
+ self.contents.append(
167
+ types.Content(
168
+ role="user",
169
+ parts=[
170
+ types.Part.from_text(text=user_message)
171
+ ],
172
+ )
173
+ )
174
+
175
+ while True:
176
+ response = self.client.models.generate_content(
177
+ model=self.model,
178
+ contents=self.contents,
179
+ config=self.config,
180
+ )
181
+
182
+ function_calls = response.function_calls
183
+
184
+ if not function_calls:
185
+ self.contents.append(response.candidates[0].content)
186
+ return response.text
187
+
188
+ self.contents.append(response.candidates[0].content)
189
+
190
+ function_responses = []
191
+
192
+ for function_call in function_calls:
193
+ tool_name = function_call.name
194
+ arguments = dict(function_call.args)
195
+
196
+ print(f"[Tool] {tool_name}({arguments})")
197
+
198
+ result = self.registry.execute(
199
+ tool_name,
200
+ arguments
201
+ )
202
+
203
+ function_responses.append(
204
+ types.Part.from_function_response(
205
+ name=tool_name,
206
+ response={
207
+ "result": result
208
+ },
209
+ )
210
+ )
211
+
212
+ self.contents.append(
213
+ types.Content(
214
+ role="user",
215
+ parts=function_responses,
216
+ )
217
+ )
File without changes
@@ -0,0 +1,17 @@
1
+ from cobie.cli.ui import console
2
+
3
+
4
+ def show_help():
5
+ console.print(
6
+ """
7
+ [bold cyan]COBIE Commands[/bold cyan]
8
+
9
+ [bold]/help[/bold] Show available commands
10
+ [bold]/clear[/bold] Clear conversation history
11
+ [bold]/exit[/bold] Exit COBIE
12
+ """
13
+ )
14
+
15
+ def clear_history(agent):
16
+ agent.contents.clear()
17
+ console.print("[green]✓ Conversation history cleared.[/green]")
@@ -0,0 +1,35 @@
1
+ from cobie.agent.agent import Agent
2
+ from cobie.cli.commands import clear_history,show_help
3
+ from cobie.cli.ui import(show_goodbye,show_message,show_response,user_prompt,welcome)
4
+ from cobie.cli.ui import ask_api_key
5
+
6
+
7
+ def run_cli():
8
+ api_key = ask_api_key()
9
+ agent = Agent(api_key)
10
+ welcome()
11
+ while True:
12
+ user_input = user_prompt()
13
+ if not user_input.strip():
14
+ continue
15
+ command = user_input.strip().lower()
16
+ if command in ("/help", "help"):
17
+ show_help()
18
+ continue
19
+
20
+ if command in ("/clear", "clear"):
21
+ clear_history(agent)
22
+ continue
23
+
24
+ if command in ("/exit", "exit"):
25
+ show_goodbye()
26
+ break
27
+ try:
28
+ show_message("COBIE is thinkingg....")
29
+ response = agent.run(user_input)
30
+ show_response(response)
31
+
32
+ except Exception as e:
33
+ show_message(f"Error:{e}")
34
+
35
+
@@ -0,0 +1,60 @@
1
+ from rich.console import Console
2
+ from rich.panel import Panel
3
+ from rich.text import Text
4
+
5
+ console = Console()
6
+
7
+
8
+ def ask_api_key():
9
+ console.print("[bold cyan]Plz paste your gemini api key.[/bold cyan]")
10
+ console.print("[dim]Your key will only be used for this session.[/dim]\n")
11
+ while True:
12
+ api_key = input("Gemini Api key :")
13
+
14
+ if api_key.strip():
15
+ return api_key.strip()
16
+
17
+ console.print("[red]API key cannot be empty.[/red]")
18
+
19
+
20
+ def welcome():
21
+ title = Text("COBIE", style="bold cyan")
22
+ subtitle = Text("Your local AI coding agent", style="dim")
23
+ subtitle2 = Text(
24
+ "Ask me anything ex: fix your project,chat,create a project ,ect", style="dim"
25
+ )
26
+ content = Text()
27
+ content.append_text(title)
28
+ content.append("\n")
29
+ content.append_text(subtitle)
30
+ content.append("\n")
31
+ content.append_text(subtitle2)
32
+
33
+ console.print(Panel(content, border_style="cyan", padding=(1, 4)))
34
+ console.print(
35
+ "[dim]Type[/dim] [bold cyan]/help[/bold cyan]"
36
+ "[dim] To see available commands.[/dim] \n"
37
+ )
38
+
39
+
40
+ def user_prompt():
41
+ return console.input("[bold cyan]> [/bold cyan]")
42
+
43
+
44
+ def show_response(res):
45
+ console.print(
46
+ Panel(
47
+ res,
48
+ title="[bold cyan]COBIE[/bold cyan]",
49
+ border_style="cyan",
50
+ padding=(1, 2),
51
+ )
52
+ )
53
+
54
+
55
+ def show_goodbye():
56
+ console.print("\n[bold cyan]Goodbye![/bold cyan]")
57
+
58
+
59
+ def show_message(message):
60
+ console.print(f"[dim]{message}[/dim]")
File without changes
@@ -0,0 +1,19 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def edit_file(path, old_text, new_text):
5
+ file_path = Path(path)
6
+
7
+ if not file_path.exists():
8
+ raise FileNotFoundError(f"File does not exist: {path}")
9
+ if not file_path.is_file():
10
+ raise ValueError(f"Path is not a file: {path}")
11
+ content = file_path.read_text()
12
+
13
+ if old_text not in content:
14
+ raise ValueError("The text to replace was not found.")
15
+
16
+ new_content = content.replace(old_text, new_text, 1)
17
+ file_path.write_text(new_content)
18
+
19
+ return "File edited successfully."
@@ -0,0 +1,32 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def read_file(path):
5
+ file_path = Path(path)
6
+
7
+ if not file_path.exists():
8
+ return "File does not exists"
9
+ return file_path.read_text()
10
+
11
+
12
+ def write_file(path, content):
13
+ file_path = Path(path)
14
+ file_path.write_text(content)
15
+ return "File written successfully."
16
+
17
+
18
+ def list_directory(path):
19
+ directory = Path(path)
20
+ lists = []
21
+ if not directory.exists():
22
+ return "The directory doesn't exists"
23
+ if not directory.is_dir():
24
+ return "Given path is not directory"
25
+ for list in directory.iterdir():
26
+ lists.append(list.name)
27
+
28
+ return lists
29
+
30
+
31
+ if __name__ == "__main__":
32
+ print(list_directory("."))
@@ -0,0 +1,7 @@
1
+ from cobie.tools.terminal import run_command
2
+
3
+ def git_status():
4
+ return run_command("git status")
5
+
6
+ def git_diff():
7
+ return run_command("git diff")
@@ -0,0 +1,30 @@
1
+ from cobie.tools.filesystem import read_file, write_file, list_directory
2
+ from cobie.tools.search import search_file
3
+ from cobie.tools.terminal import run_command
4
+ from cobie.tools.git import git_diff, git_status
5
+ from cobie.tools.edit import edit_file
6
+
7
+
8
+ class ToolRegister:
9
+ def __init__(self):
10
+ self.tools = {
11
+ "read_file": read_file,
12
+ "write_file": write_file,
13
+ "list_directory": list_directory,
14
+ "search_file": search_file,
15
+ "run_command": run_command,
16
+ "git_status": git_status,
17
+ "git_diff": git_diff,
18
+ "edit_file": edit_file,
19
+ }
20
+
21
+ def execute(self, name, args):
22
+ if name not in self.tools:
23
+ return {"success": False, "error": f"Unknown tool: {name}"}
24
+
25
+ tool = self.tools[name]
26
+ try:
27
+ result = tool(**args)
28
+ return {"success": True, "result": result}
29
+ except Exception as e:
30
+ return {"success": False, "error": str(e)}
@@ -0,0 +1,18 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def search_file(query, path="."):
5
+ root = Path(path)
6
+ result = []
7
+
8
+ for file in root.rglob("*"):
9
+ if not file.is_file():
10
+ continue
11
+ try:
12
+ content = file.read_text()
13
+ except Exception:
14
+ continue
15
+
16
+ if query in content:
17
+ result.append(str(file))
18
+ return result
@@ -0,0 +1,12 @@
1
+ import subprocess
2
+
3
+ def run_command(command):
4
+ result = subprocess.run(
5
+ command,shell=True,capture_output=True,text=True
6
+ )
7
+
8
+ return{
9
+ "stdout":result.stdout,
10
+ "stderr":result.stderr,
11
+ "returncode":result.returncode
12
+ }
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: cobie
3
+ Version: 1.0
4
+ Summary: Your local AI coding agent
5
+ Author: Xitiz mgr
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: google-genai
9
+ Requires-Dist: rich
10
+ Requires-Dist: python-dotenv
11
+
12
+ # What is COBIE
13
+
14
+ > COBIE is your local ai
15
+ > COBIE is a local AI coding agent that works directly with your project through the terminal.
16
+
17
+ ![alt text](image-1.png)
18
+
19
+ Cobie is powered by gemini api . which u can get it for free in _ https://aistudio.google.com/api-keys _
20
+
21
+ ## Feature
22
+
23
+ - directly run on terminal no need to copy paste and ask llm for fixing u can directly fix it
24
+ - Read file
25
+ - Write file
26
+ - edit file , etc
27
+
28
+ # Tech Stack
29
+
30
+ - python
31
+ - Rich for terminal ui
32
+ - google gemini api key
33
+ - python subprocess module
@@ -0,0 +1,23 @@
1
+ README.md
2
+ pyproject.toml
3
+ cobie/__init__.py
4
+ cobie/__main__.py
5
+ cobie.egg-info/PKG-INFO
6
+ cobie.egg-info/SOURCES.txt
7
+ cobie.egg-info/dependency_links.txt
8
+ cobie.egg-info/entry_points.txt
9
+ cobie.egg-info/requires.txt
10
+ cobie.egg-info/top_level.txt
11
+ cobie/agent/__init__.py
12
+ cobie/agent/agent.py
13
+ cobie/cli/__init__.py
14
+ cobie/cli/commands.py
15
+ cobie/cli/main.py
16
+ cobie/cli/ui.py
17
+ cobie/tools/__init__.py
18
+ cobie/tools/edit.py
19
+ cobie/tools/filesystem.py
20
+ cobie/tools/git.py
21
+ cobie/tools/registry.py
22
+ cobie/tools/search.py
23
+ cobie/tools/terminal.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cobie = cobie.cli.main:run_cli
@@ -0,0 +1,3 @@
1
+ google-genai
2
+ rich
3
+ python-dotenv
@@ -0,0 +1 @@
1
+ cobie
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cobie"
7
+ version = "1.0"
8
+ description = "Your local AI coding agent"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [
12
+ { name = "Xitiz mgr" }
13
+ ]
14
+ dependencies = [
15
+ "google-genai",
16
+ "rich",
17
+ "python-dotenv"
18
+ ]
19
+
20
+ [project.scripts]
21
+ cobie = "cobie.cli.main:run_cli"
22
+
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["."]
26
+ include = ["cobie*"]
27
+ exclude = ["venv*"]
cobie-1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+