vibecore 0.5.0__py3-none-any.whl → 0.6.0__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.

Potentially problematic release.


This version of vibecore might be problematic. Click here for more details.

@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
3
3
  from agents import Agent
4
4
  from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
5
5
 
6
- from vibecore.context import VibecoreContext
6
+ from vibecore.context import FullVibecoreContext
7
7
  from vibecore.settings import settings
8
8
  from vibecore.tools.file.tools import edit, multi_edit, read, write
9
9
  from vibecore.tools.python.tools import execute_python
@@ -29,7 +29,7 @@ INSTRUCTIONS = (
29
29
  )
30
30
 
31
31
 
32
- def create_default_agent(mcp_servers: list["MCPServer"] | None = None) -> Agent[VibecoreContext]:
32
+ def create_default_agent(mcp_servers: list["MCPServer"] | None = None) -> Agent[FullVibecoreContext]:
33
33
  """Create the general-purpose agent with appropriate tools.
34
34
 
35
35
  Args:
@@ -58,7 +58,7 @@ def create_default_agent(mcp_servers: list["MCPServer"] | None = None) -> Agent[
58
58
 
59
59
  instructions = prompt_with_handoff_instructions(instructions)
60
60
 
61
- return Agent[VibecoreContext](
61
+ return Agent[FullVibecoreContext](
62
62
  name="Vibecore Agent",
63
63
  handoff_description="A versatile general-purpose assistant",
64
64
  instructions=instructions,
vibecore/agents/task.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from agents import Agent
4
4
  from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
5
5
 
6
- from vibecore.context import VibecoreContext
6
+ from vibecore.context import FullVibecoreContext
7
7
  from vibecore.settings import settings
8
8
  from vibecore.tools.file.tools import edit, multi_edit, read, write
9
9
  from vibecore.tools.python.tools import execute_python
@@ -13,7 +13,7 @@ from vibecore.tools.todo.tools import todo_read, todo_write
13
13
  from .prompts import COMMON_PROMPT
14
14
 
15
15
 
16
- def create_task_agent(prompt: str) -> Agent[VibecoreContext]:
16
+ def create_task_agent(prompt: str) -> Agent[FullVibecoreContext]:
17
17
  """Create a task agent with all tools except the Task tool.
18
18
 
19
19
  This agent is used by the Task tool to execute specific tasks.
@@ -51,7 +51,7 @@ def create_task_agent(prompt: str) -> Agent[VibecoreContext]:
51
51
 
52
52
  instructions = prompt_with_handoff_instructions(instructions)
53
53
 
54
- return Agent[VibecoreContext](
54
+ return Agent[FullVibecoreContext](
55
55
  name="Task Agent",
56
56
  handoff_description="A task-specific agent",
57
57
  instructions=instructions,
vibecore/cli.py CHANGED
@@ -1,17 +1,21 @@
1
1
  """Vibecore CLI interface using typer."""
2
2
 
3
3
  import asyncio
4
+ import contextlib
5
+ import datetime
4
6
  import logging
7
+ import sys
5
8
  from importlib.metadata import version
6
9
  from pathlib import Path
7
10
 
8
11
  import typer
12
+ from agents.result import RunResultBase
9
13
  from textual.logging import TextualHandler
10
14
 
11
15
  from vibecore.agents.default import create_default_agent
12
- from vibecore.context import VibecoreContext
13
- from vibecore.main import VibecoreApp
16
+ from vibecore.flow import AppIsExiting, Vibecore, VibecoreRunner
14
17
  from vibecore.mcp import MCPManager
18
+ from vibecore.session import JSONLSession
15
19
  from vibecore.settings import settings
16
20
 
17
21
  app = typer.Typer()
@@ -110,49 +114,70 @@ def main(
110
114
  logger = logging.getLogger("openai.agents")
111
115
  logger.addHandler(TextualHandler())
112
116
 
113
- # Create context
114
- vibecore_ctx = VibecoreContext()
115
-
116
- # Initialize MCP manager if configured
117
- mcp_servers = []
118
- if settings.mcp_servers:
119
- # Create MCP manager
120
- mcp_manager = MCPManager(settings.mcp_servers)
121
- vibecore_ctx.mcp_manager = mcp_manager
122
-
123
- # Get the MCP servers from the manager
124
- mcp_servers = mcp_manager.servers
117
+ asyncio.run(
118
+ async_main(continue_session=continue_session, session_id=session_id, prompt=prompt, print_mode=print_mode)
119
+ )
125
120
 
126
- # Create agent with MCP servers
127
- agent = create_default_agent(mcp_servers=mcp_servers)
128
121
 
129
- # Determine session to use
130
- session_to_load = None
131
- if continue_session:
132
- session_to_load = find_latest_session()
133
- if not session_to_load:
134
- typer.echo("No existing sessions found for this project.")
135
- raise typer.Exit(1)
136
- typer.echo(f"Continuing session: {session_to_load}")
137
- elif session_id:
138
- session_to_load = session_id
139
- typer.echo(f"Loading session: {session_to_load}")
140
-
141
- # Create app
142
- app_instance = VibecoreApp(vibecore_ctx, agent, session_id=session_to_load, print_mode=print_mode)
143
-
144
- if print_mode:
145
- # Run in print mode
146
- import asyncio
147
-
148
- # Use provided prompt or None to read from stdin
149
- result = asyncio.run(app_instance.run_print(prompt))
150
- # Print raw output to stdout
151
- if result:
152
- print(result)
153
- else:
154
- # Run normal TUI mode
155
- app_instance.run()
122
+ async def async_main(continue_session: bool, session_id: str | None, prompt: str | None, print_mode: bool):
123
+ # Create MCP manager
124
+ async with MCPManager(settings.mcp_servers) as mcp_manager:
125
+ # Create agent with MCP servers
126
+ agent = create_default_agent(mcp_servers=mcp_manager.servers)
127
+
128
+ # Create Vibecore instance
129
+ from vibecore.context import FullVibecoreContext
130
+
131
+ vibecore = Vibecore[FullVibecoreContext, RunResultBase](disable_user_input=False)
132
+
133
+ # Determine session to use
134
+ session_to_load = None
135
+ if continue_session:
136
+ session_to_load = find_latest_session()
137
+ if not session_to_load:
138
+ typer.echo("No existing sessions found for this project.")
139
+ raise typer.Exit(1)
140
+ typer.echo(f"Continuing session: {session_to_load}")
141
+ elif session_id:
142
+ session_to_load = session_id
143
+ typer.echo(f"Loading session: {session_to_load}")
144
+
145
+ if session_to_load is None:
146
+ # Generate a new session ID based on current date/time
147
+ session_to_load = f"chat-{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}"
148
+
149
+ session = JSONLSession(
150
+ session_id=session_to_load,
151
+ project_path=None, # Will use current working directory
152
+ base_dir=settings.session.base_dir,
153
+ )
154
+
155
+ # Define workflow logic
156
+ @vibecore.workflow()
157
+ async def workflow(
158
+ runner: VibecoreRunner[FullVibecoreContext, RunResultBase],
159
+ user_message: str,
160
+ ) -> RunResultBase:
161
+ # Run the agent with the input
162
+ return await runner.run_agent(
163
+ agent,
164
+ input=user_message,
165
+ context=runner.context,
166
+ max_turns=settings.max_turns,
167
+ session=runner.session,
168
+ )
169
+
170
+ if print_mode:
171
+ # Use static runner for print mode - pass empty input since we get it in workflow
172
+ input_text = prompt.strip() if prompt else sys.stdin.read().strip()
173
+ result = await vibecore.run(input_text)
174
+ # Print raw output to stdout
175
+ print(result.final_output_as(str))
176
+ else:
177
+ # Run in TUI mode
178
+ with contextlib.suppress(AppIsExiting):
179
+ result = await vibecore.run_textual(prompt, session=session)
180
+ print(result)
156
181
 
157
182
 
158
183
  @auth_app.command("login")
vibecore/context.py CHANGED
@@ -1,29 +1,61 @@
1
1
  from dataclasses import dataclass, field
2
2
  from pathlib import Path
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING, Optional, Protocol, runtime_checkable
4
4
 
5
5
  from vibecore.tools.python.manager import PythonExecutionManager
6
6
  from vibecore.tools.todo.manager import TodoManager
7
7
 
8
8
  if TYPE_CHECKING:
9
9
  from vibecore.main import VibecoreApp
10
- from vibecore.mcp import MCPManager
11
10
  from vibecore.tools.path_validator import PathValidator
12
11
 
13
12
 
13
+ @runtime_checkable
14
+ class TodoToolContext(Protocol):
15
+ """Context required by todo tools."""
16
+
17
+ todo_manager: TodoManager
18
+
19
+
20
+ @runtime_checkable
21
+ class PythonToolContext(Protocol):
22
+ """Context required by Python execution tools."""
23
+
24
+ python_manager: PythonExecutionManager
25
+
26
+
27
+ @runtime_checkable
28
+ class PathValidatorContext(Protocol):
29
+ """Context that provides a path validator for file-system tools."""
30
+
31
+ path_validator: "PathValidator"
32
+
33
+
34
+ @runtime_checkable
35
+ class AppAwareContext(Protocol):
36
+ """Context that exposes the optional Textual app for streaming updates."""
37
+
38
+ app: Optional["VibecoreApp"]
39
+
40
+
41
+ @runtime_checkable
42
+ class FullVibecoreContext(TodoToolContext, PythonToolContext, PathValidatorContext, AppAwareContext, Protocol):
43
+ """Protocol describing the full context required by Vibecore agents."""
44
+
45
+ ...
46
+
47
+
14
48
  @dataclass
15
- class VibecoreContext:
49
+ class DefaultVibecoreContext:
16
50
  todo_manager: TodoManager = field(default_factory=TodoManager)
17
51
  python_manager: PythonExecutionManager = field(default_factory=PythonExecutionManager)
18
52
  app: Optional["VibecoreApp"] = None
19
- context_fullness: float = 0.0
20
- mcp_manager: Optional["MCPManager"] = None
21
53
 
22
54
  # Path confinement configuration
23
55
  allowed_directories: list[Path] = field(default_factory=list)
24
56
  path_validator: "PathValidator" = field(init=False) # Always initialized, never None
25
57
 
26
- def __post_init__(self):
58
+ def __post_init__(self) -> None:
27
59
  """Initialize path validator with allowed directories."""
28
60
  from vibecore.tools.path_validator import PathValidator
29
61
 
@@ -49,13 +81,7 @@ class VibecoreContext:
49
81
 
50
82
  self.path_validator = PathValidator(self.allowed_directories)
51
83
 
52
- def reset_state(self) -> None:
53
- """Reset all context state for a new session."""
54
- self.todo_manager = TodoManager()
55
- self.python_manager = PythonExecutionManager()
56
- self.context_fullness = 0.0
57
- # Preserve allowed_directories across resets
58
- # Re-initialize validator in case directories changed
59
- from vibecore.tools.path_validator import PathValidator
60
84
 
61
- self.path_validator = PathValidator(self.allowed_directories)
85
+ if TYPE_CHECKING:
86
+ # Ensure DefaultVibecoreContext conforms to the VibecoreContext protocol for static analyzers
87
+ _default_context: FullVibecoreContext = DefaultVibecoreContext()