raggiecode 0.2.1__py3-none-any.whl

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.
Files changed (93) hide show
  1. Agent/__init__.py +0 -0
  2. Agent/agent.py +891 -0
  3. Agent/chat_history_db.py +1500 -0
  4. Agent/command.py +49 -0
  5. Agent/config.py +46 -0
  6. Agent/effort_levels.py +33 -0
  7. Agent/git_manager.py +727 -0
  8. Agent/tools.py +35 -0
  9. Commands/__init__.py +18 -0
  10. Commands/effort.py +42 -0
  11. Commands/global_todo.py +23 -0
  12. Commands/help.py +22 -0
  13. Commands/reasoning.py +24 -0
  14. Commands/redo.py +11 -0
  15. Commands/reindex.py +27 -0
  16. Commands/shell.py +28 -0
  17. Commands/stream.py +24 -0
  18. Commands/undo.py +13 -0
  19. Commands/unlimited_effort.py +8 -0
  20. Commands/window_size.py +29 -0
  21. RAG/__init__.py +0 -0
  22. RAG/document.py +119 -0
  23. RAG/find.py +408 -0
  24. RAG/graph.py +231 -0
  25. Tools/GetFileCodeStructure.py +43 -0
  26. Tools/GetSymbolSourceCode.py +27 -0
  27. Tools/__init__.py +39 -0
  28. Tools/ask_user.py +102 -0
  29. Tools/dispatch_subagent.py +215 -0
  30. Tools/document.py +35 -0
  31. Tools/edit_symbol.py +250 -0
  32. Tools/fuzzy_search.py +119 -0
  33. Tools/list_dir.py +51 -0
  34. Tools/read.py +49 -0
  35. Tools/read_image.py +75 -0
  36. Tools/remove.py +75 -0
  37. Tools/replace.py +305 -0
  38. Tools/search.py +41 -0
  39. Tools/shell.py +149 -0
  40. Tools/shell_kill.py +87 -0
  41. Tools/temp_background_service.py +113 -0
  42. Tools/todo_list.py +481 -0
  43. Tools/utils.py +116 -0
  44. Tools/view_changes.py +179 -0
  45. Tools/walk_call_tree.py +30 -0
  46. Tools/web_fetch.py +175 -0
  47. Tools/web_search.py +69 -0
  48. Tools/write.py +48 -0
  49. cli.py +111 -0
  50. config/__init__.py +0 -0
  51. config/coder_system_prompt.md +119 -0
  52. config/roles.json +43 -0
  53. config/tools.json +709 -0
  54. indexing/__init__.py +0 -0
  55. indexing/cli.py +128 -0
  56. indexing/code_index_sdk.py +832 -0
  57. indexing/code_indexer.py +1763 -0
  58. indexing/db_schema.py +396 -0
  59. indexing/export_to_json.py +346 -0
  60. indexing/extractors.py +189 -0
  61. indexing/file_utils.py +97 -0
  62. indexing/frontend/__init__.py +0 -0
  63. indexing/frontend/css_extractor.py +195 -0
  64. indexing/frontend/css_parser.py +387 -0
  65. indexing/frontend/css_selector_utils.py +226 -0
  66. indexing/frontend/edit_safety.py +573 -0
  67. indexing/frontend/graph.py +838 -0
  68. indexing/frontend/html_extractor.py +496 -0
  69. indexing/frontend/html_parser.py +314 -0
  70. indexing/frontend/jsx_extractor.py +1204 -0
  71. indexing/frontend/location_lookup.py +247 -0
  72. indexing/frontend/resolver.py +485 -0
  73. indexing/frontend/runtime_resolver.py +862 -0
  74. indexing/frontend/semantic_output.py +705 -0
  75. indexing/frontend/source_location.py +69 -0
  76. indexing/frontend_config.py +72 -0
  77. indexing/frontend_models.py +347 -0
  78. indexing/language_config.py +360 -0
  79. indexing/models.py +284 -0
  80. indexing/node_utils.py +1112 -0
  81. indexing/parse_worker.py +1082 -0
  82. indexing/queries.py +1542 -0
  83. indexing/sdk_examples.py +426 -0
  84. interactive.py +248 -0
  85. raggie.py +673 -0
  86. raggiecode-0.2.1.dist-info/METADATA +944 -0
  87. raggiecode-0.2.1.dist-info/RECORD +93 -0
  88. raggiecode-0.2.1.dist-info/WHEEL +5 -0
  89. raggiecode-0.2.1.dist-info/entry_points.txt +2 -0
  90. raggiecode-0.2.1.dist-info/top_level.txt +10 -0
  91. skills/__init__.py +3 -0
  92. skills/manager.py +114 -0
  93. skills/tool.py +121 -0
Agent/tools.py ADDED
@@ -0,0 +1,35 @@
1
+ import inspect
2
+
3
+
4
+ class ToolRegistry:
5
+
6
+ def __init__(self):
7
+ self.tools = {}
8
+ self.agent_role = None
9
+ self.code_indexer = None
10
+
11
+ def set_handler(self, name, callback):
12
+ self.tools[name] = callback
13
+
14
+ def call(self, name, arguments, toolcall_id, parent_session_id=None):
15
+ if name not in self.tools:
16
+ raise KeyError(f"Tool '{name}' is not registered")
17
+
18
+ tool = self.tools[name]
19
+ signature = inspect.signature(tool)
20
+ params = signature.parameters
21
+ has_agent_role = "agent_role" in params
22
+ has_parent_session_id = "parent_session_id" in params
23
+
24
+ kwargs = {}
25
+ if "code_indexer" in params:
26
+ kwargs["code_indexer"] = self.code_indexer
27
+
28
+ if has_agent_role and has_parent_session_id:
29
+ return tool(arguments, toolcall_id, self.agent_role, parent_session_id, **kwargs)
30
+ if has_agent_role:
31
+ return tool(arguments, toolcall_id, self.agent_role, **kwargs)
32
+ if has_parent_session_id or "session_id" in params:
33
+ return tool(arguments, toolcall_id, parent_session_id, **kwargs)
34
+
35
+ return tool(arguments, toolcall_id, **kwargs)
Commands/__init__.py ADDED
@@ -0,0 +1,18 @@
1
+ from Agent.command import CommandRegistry
2
+
3
+
4
+ def setup_commands(registry: CommandRegistry):
5
+ """Register all user-facing commands with the registry."""
6
+ from . import undo, redo, shell, stream, reasoning, window_size, help, global_todo, effort, unlimited_effort, reindex
7
+
8
+ registry.register("/undo", undo.handle)
9
+ registry.register("/redo", redo.handle)
10
+ registry.register("!", shell.handle)
11
+ registry.register("/streaming", stream.handle)
12
+ registry.register("/reasoning", reasoning.handle)
13
+ registry.register("/windowSize", window_size.handle)
14
+ registry.register("/help", help.handle)
15
+ registry.register("/globalTodo", global_todo.handle)
16
+ registry.register("/effort", effort.handle)
17
+ registry.register("/unlimitedEffort", unlimited_effort.handle)
18
+ registry.register("/reindex", reindex.handle)
Commands/effort.py ADDED
@@ -0,0 +1,42 @@
1
+ def handle(args, agent):
2
+ """Set or show the effort level for the current session.
3
+
4
+ Usage:
5
+ /effort Show current effort level and available options
6
+ /effort <num> Set effort by number (1-5)
7
+ /effort <name> Set effort by name (zen, serious, extreme, feral, insane)
8
+ """
9
+ from Agent.effort_levels import EFFORT_LEVELS, effort_name
10
+ from Agent.chat_history_db import get_session_effort, set_session_effort
11
+
12
+ arg = args.strip()
13
+
14
+ if not arg:
15
+ from interactive import _prompt_effort
16
+ _prompt_effort(agent.session_id)
17
+ return ""
18
+
19
+ # Try numeric match
20
+ try:
21
+ effort = int(arg)
22
+ except ValueError:
23
+ # Try name match (case-insensitive)
24
+ lower = arg.lower()
25
+ for num, info in EFFORT_LEVELS.items():
26
+ if info["name"].lower() == lower:
27
+ effort = num
28
+ break
29
+ else:
30
+ print(f"Unknown effort level: {arg}")
31
+ print(f"Available: {', '.join(info['name'] for info in EFFORT_LEVELS.values())}")
32
+ return ""
33
+
34
+ if effort not in EFFORT_LEVELS:
35
+ print(f"Invalid effort level: {effort}")
36
+ print(f"Pick a number between 1 and {len(EFFORT_LEVELS)}")
37
+ return ""
38
+
39
+ set_session_effort(agent.session_id, effort)
40
+ print(f"Effort: {EFFORT_LEVELS[effort]['name']}")
41
+
42
+ return ""
@@ -0,0 +1,23 @@
1
+ def handle(args, agent):
2
+ """Toggle global todo list mode on/off mid-conversation.
3
+
4
+ When enabled, todo lists are shared across all subagent sessions.
5
+ Usage: /globalTodo on or /globalTodo off
6
+ """
7
+ from Agent.config import save_roles
8
+
9
+ arg = args.strip().lower()
10
+
11
+ if arg in ("on", "true", "yes"):
12
+ agent.roles[agent.agent_role]["globalTodo"] = True
13
+ save_roles(agent.roles)
14
+ print("Global todo: on (saved) — todo lists are now shared across all subagent sessions")
15
+ elif arg in ("off", "false", "no"):
16
+ agent.roles[agent.agent_role]["globalTodo"] = False
17
+ save_roles(agent.roles)
18
+ print("Global todo: off (saved) — todo lists are session-scoped")
19
+ else:
20
+ state = "on" if agent.roles.get(agent.agent_role, {}).get("globalTodo", False) else "off"
21
+ print(f"Global todo: {state} (usage: /globalTodo on|off)")
22
+
23
+ return ""
Commands/help.py ADDED
@@ -0,0 +1,22 @@
1
+ def handle(args, agent):
2
+ """Show available in-chat commands."""
3
+ print()
4
+ print("Available commands:")
5
+ print()
6
+ print(" /undo Undo the last agent commit")
7
+ print(" /redo Re-apply the last undone commit")
8
+ print(" /streaming on|off Toggle streaming mode (persists to roles.json)")
9
+ print(" /reasoning on|off Toggle reasoning output (persists to roles.json)")
10
+ print(" /windowSize <num> Set context window size in tokens (persists to roles.json)")
11
+ print(" /globalTodo on|off Toggle shared todo lists across subagents (persists to roles.json)")
12
+ print(" /effort <num|name> Set effort level (1-5 or zen, serious, extreme, feral, insane)")
13
+ print(" /reindex [--force] Re-index the codebase (use --force to re-index all files)")
14
+ print(" /help Show this help message")
15
+ print(" !<command> Run a shell command (e.g. !ls -la)")
16
+ print()
17
+ print(" Ctrl+C Go back (exits too)")
18
+ print(" Ctrl+D Leave the chat")
19
+ print()
20
+ print("Press Esc followed by Enter to send message, or type 'exit' to quit")
21
+
22
+ return ""
Commands/reasoning.py ADDED
@@ -0,0 +1,24 @@
1
+ def handle(args, agent):
2
+ """Toggle reasoning mode on/off mid-conversation.
3
+
4
+ Usage: /reasoning on or /reasoning off
5
+ """
6
+ from Agent.config import save_roles
7
+
8
+ arg = args.strip().lower()
9
+
10
+ if arg in ("on", "true", "yes"):
11
+ agent.reasoning = True
12
+ agent.roles[agent.agent_role]["reasoning"] = True
13
+ save_roles(agent.roles)
14
+ print("Reasoning: on (saved)")
15
+ elif arg in ("off", "false", "no"):
16
+ agent.reasoning = False
17
+ agent.roles[agent.agent_role]["reasoning"] = False
18
+ save_roles(agent.roles)
19
+ print("Reasoning: off (saved)")
20
+ else:
21
+ state = "on" if agent.reasoning else "off"
22
+ print(f"Reasoning: {state} (usage: /reasoning on|off)")
23
+
24
+ return ""
Commands/redo.py ADDED
@@ -0,0 +1,11 @@
1
+ def handle(args, agent):
2
+ BLUE = "\033[34m"
3
+ RESET = "\033[0m"
4
+
5
+ redone_commit = agent.git_manager.redo_last_commit()
6
+ if redone_commit:
7
+ print(f"Redone to commit: {redone_commit}\n")
8
+ print(f"{BLUE}type /undo to undo the last code changes{RESET}")
9
+ else:
10
+ print("Nothing to redo")
11
+ return ""
Commands/reindex.py ADDED
@@ -0,0 +1,27 @@
1
+ def handle(args, agent):
2
+ """Manually trigger re-indexing of the codebase.
3
+
4
+ Usage:
5
+ /reindex Index new/changed files (incremental)
6
+ /reindex --force Force re-index all files from scratch
7
+ """
8
+ force = "--force" in args
9
+
10
+ if agent.code_indexer is None:
11
+ print("No code indexer available.")
12
+ return ""
13
+
14
+ try:
15
+ if force:
16
+ print("Force re-indexing all files...")
17
+ else:
18
+ print("Re-indexing changed files...")
19
+ agent.code_indexer.index_directory(force_reindex=force)
20
+ print("Indexing complete.")
21
+ except (KeyboardInterrupt, EOFError):
22
+ print("\nRe-indexing interrupted.")
23
+ agent.code_indexer._connect()
24
+ except Exception as e:
25
+ print(f"Re-indexing failed: {e}")
26
+
27
+ return ""
Commands/shell.py ADDED
@@ -0,0 +1,28 @@
1
+ import subprocess
2
+
3
+
4
+ def handle(args, agent):
5
+ """Handle the ! shell command.
6
+
7
+ Runs *args* as a shell command and returns the combined output.
8
+
9
+ Args:
10
+ args: The shell command string (everything after ``!``).
11
+ agent: The Agent instance (unused).
12
+
13
+ Returns:
14
+ Empty string (agent does nothing; output is printed directly).
15
+ """
16
+ if not args:
17
+ return ""
18
+ try:
19
+ result = subprocess.run(
20
+ args, shell=True, capture_output=True, text=True
21
+ )
22
+ if result.stdout:
23
+ print(result.stdout)
24
+ if result.stderr:
25
+ print(result.stderr)
26
+ except Exception as e:
27
+ print(f"Error executing command: {e}")
28
+ return ""
Commands/stream.py ADDED
@@ -0,0 +1,24 @@
1
+ def handle(args, agent):
2
+ """Toggle streaming mode on/off mid-conversation.
3
+
4
+ Usage: /streaming on or /streaming off
5
+ """
6
+ from Agent.config import save_roles
7
+
8
+ arg = args.strip().lower()
9
+
10
+ if arg in ("on", "true", "yes"):
11
+ agent.streaming = True
12
+ agent.roles[agent.agent_role]["stream"] = True
13
+ save_roles(agent.roles)
14
+ print("Streaming: on (saved)")
15
+ elif arg in ("off", "false", "no"):
16
+ agent.streaming = False
17
+ agent.roles[agent.agent_role]["stream"] = False
18
+ save_roles(agent.roles)
19
+ print("Streaming: off (saved)")
20
+ else:
21
+ state = "on" if agent.streaming else "off"
22
+ print(f"Streaming: {state} (usage: /stream on|off)")
23
+
24
+ return ""
Commands/undo.py ADDED
@@ -0,0 +1,13 @@
1
+ def handle(args, agent):
2
+ previous_commit = agent.git_manager.undo_last_commit()
3
+
4
+ BLUE = "\033[34m"
5
+ RESET = "\033[0m"
6
+
7
+ if previous_commit:
8
+ print(f"Undid to commit: {previous_commit}\n")
9
+ print(f"{BLUE}type /redo to redo the last code changes{RESET}")
10
+
11
+ else:
12
+ print("No previous commit to undo")
13
+ return ""
@@ -0,0 +1,8 @@
1
+ def handle(args, agent):
2
+ """Secret command to set truly unlimited effort depth."""
3
+ from Agent.effort_levels import UNLIMITED_EFFORT
4
+ from Agent.chat_history_db import set_session_effort
5
+
6
+ set_session_effort(agent.session_id, UNLIMITED_EFFORT)
7
+ print("Effort: Unlimited")
8
+ return ""
@@ -0,0 +1,29 @@
1
+ def handle(args, agent):
2
+ """Set the context window size mid-conversation.
3
+
4
+ Usage: /WindowSize 202752
5
+ """
6
+ from Agent.config import save_roles
7
+
8
+ arg = args.strip()
9
+
10
+ if not arg:
11
+ current = agent.roles[agent.agent_role].get("context_window", "?")
12
+ print(f"Context window: {current} (usage: /WindowSize <number>)")
13
+ return ""
14
+
15
+ try:
16
+ value = int(arg)
17
+ except ValueError:
18
+ print(f"Invalid value '{arg}'. Must be a number.")
19
+ return ""
20
+
21
+ if value <= 0:
22
+ print("Context window must be positive.")
23
+ return ""
24
+
25
+ agent.roles[agent.agent_role]["context_window"] = value
26
+ save_roles(agent.roles)
27
+ print(f"Context window: {value} (saved)")
28
+
29
+ return ""
RAG/__init__.py ADDED
File without changes
RAG/document.py ADDED
@@ -0,0 +1,119 @@
1
+ from pathlib import Path
2
+
3
+ from indexing.code_index_sdk import CodeIndexSDK
4
+
5
+
6
+ def get_symbol_description(symbol_name: str, symbol_type: str = "function", file_path: str = None) -> str:
7
+ """Get the description of a symbol from the code index database.
8
+
9
+ Args:
10
+ symbol_name: Name of the symbol to query
11
+ symbol_type: Type of symbol ("function", "method", "class", or "variable")
12
+ file_path: Optional file path to disambiguate same-name symbols
13
+
14
+ Returns:
15
+ Description string or error message
16
+ """
17
+ db_path = Path.cwd() / ".raggie" / ".code_index.raggie"
18
+
19
+ if not db_path.exists():
20
+ return f"Error: Code index database not found at {db_path}"
21
+
22
+ with CodeIndexSDK(str(db_path)) as sdk:
23
+ description = sdk.get_symbol_description_by_name(symbol_type, symbol_name, file_path)
24
+
25
+ if description is None:
26
+ return f"No description found for {symbol_type} '{symbol_name}'" + (f" in '{file_path}'" if file_path else "")
27
+
28
+ return description
29
+
30
+
31
+ def update_symbol_description(symbol_name: str, description: str, symbol_type: str = "function", file_path: str = None) -> str:
32
+ """Update the description of a symbol in the code index database.
33
+
34
+ Args:
35
+ symbol_name: Name of the symbol to update
36
+ description: The description to set
37
+ symbol_type: Type of symbol ("function", "method", "class", or "variable")
38
+ file_path: Optional file path to disambiguate same-name symbols
39
+
40
+ Returns:
41
+ Success message or error message
42
+ """
43
+ db_path = Path.cwd() / ".raggie" / ".code_index.raggie"
44
+
45
+ if not db_path.exists():
46
+ return f"Error: Code index database not found at {db_path}"
47
+
48
+ with CodeIndexSDK(str(db_path)) as sdk:
49
+ if symbol_type in ("function", "method"):
50
+ matches = sdk.get_function_by_name(symbol_name)
51
+ if not matches:
52
+ return f"Error: {symbol_type.capitalize()} '{symbol_name}' not found in code index."
53
+
54
+ # Filter by type if method
55
+ if symbol_type == "method":
56
+ matches = [f for f in matches if f.type == "method"]
57
+ if not matches:
58
+ return f"Error: Method '{symbol_name}' not found in code index."
59
+
60
+ # If file_path provided, filter by file
61
+ if file_path:
62
+ matches = [f for f in matches if f.file_path == file_path]
63
+ if not matches:
64
+ return f"Error: {symbol_type.capitalize()} '{symbol_name}' not found in file '{file_path}'."
65
+
66
+ func = matches[0]
67
+ cursor = sdk.conn.cursor()
68
+ cursor.execute(
69
+ "UPDATE functions SET description = ? WHERE id = ?",
70
+ (description, func.id)
71
+ )
72
+ sdk.conn.commit()
73
+
74
+ return f"Successfully updated description for {symbol_type} '{symbol_name}' in '{func.file_path}'"
75
+
76
+ elif symbol_type == "class":
77
+ matches = sdk.get_class_by_name(symbol_name)
78
+ if not matches:
79
+ return f"Error: Class '{symbol_name}' not found in code index."
80
+
81
+ # If file_path provided, filter by file
82
+ if file_path:
83
+ matches = [c for c in matches if c.file_path == file_path]
84
+ if not matches:
85
+ return f"Error: Class '{symbol_name}' not found in file '{file_path}'."
86
+
87
+ cls = matches[0]
88
+ cursor = sdk.conn.cursor()
89
+ cursor.execute(
90
+ "UPDATE classes SET description = ? WHERE id = ?",
91
+ (description, cls.id)
92
+ )
93
+ sdk.conn.commit()
94
+
95
+ return f"Successfully updated description for class '{symbol_name}' in '{cls.file_path}'"
96
+
97
+ elif symbol_type == "variable":
98
+ matches = sdk.get_variable_by_name(symbol_name)
99
+ if not matches:
100
+ return f"Error: Variable '{symbol_name}' not found in code index."
101
+
102
+ # If file_path provided, filter by file
103
+ if file_path:
104
+ matches = [v for v in matches if v.file_path == file_path]
105
+ if not matches:
106
+ return f"Error: Variable '{symbol_name}' not found in file '{file_path}'."
107
+
108
+ var = matches[0]
109
+ cursor = sdk.conn.cursor()
110
+ cursor.execute(
111
+ "UPDATE variables SET description = ? WHERE id = ?",
112
+ (description, var.id)
113
+ )
114
+ sdk.conn.commit()
115
+
116
+ return f"Successfully updated description for variable '{symbol_name}' in '{var.file_path}'"
117
+
118
+ else:
119
+ return f"Error: Invalid symbol_type '{symbol_type}'. Must be 'function', 'method', 'class', or 'variable'."