vibecore 0.2.0a1__tar.gz → 0.3.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.

Potentially problematic release.


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

Files changed (86) hide show
  1. {vibecore-0.2.0a1 → vibecore-0.3.0}/PKG-INFO +107 -1
  2. {vibecore-0.2.0a1 → vibecore-0.3.0}/README.md +103 -0
  3. {vibecore-0.2.0a1 → vibecore-0.3.0}/pyproject.toml +5 -2
  4. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/agents/default.py +6 -11
  5. vibecore-0.2.0a1/src/vibecore/agents/task_agent.py → vibecore-0.3.0/src/vibecore/agents/task.py +2 -6
  6. vibecore-0.3.0/src/vibecore/auth/__init__.py +15 -0
  7. vibecore-0.3.0/src/vibecore/auth/config.py +38 -0
  8. vibecore-0.3.0/src/vibecore/auth/interceptor.py +141 -0
  9. vibecore-0.3.0/src/vibecore/auth/manager.py +173 -0
  10. vibecore-0.3.0/src/vibecore/auth/models.py +54 -0
  11. vibecore-0.3.0/src/vibecore/auth/oauth_flow.py +129 -0
  12. vibecore-0.3.0/src/vibecore/auth/pkce.py +29 -0
  13. vibecore-0.3.0/src/vibecore/auth/storage.py +111 -0
  14. vibecore-0.3.0/src/vibecore/auth/token_manager.py +131 -0
  15. vibecore-0.3.0/src/vibecore/cli.py +239 -0
  16. vibecore-0.3.0/src/vibecore/flow.py +105 -0
  17. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/handlers/stream_handler.py +11 -0
  18. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/main.py +28 -6
  19. vibecore-0.3.0/src/vibecore/models/anthropic_auth.py +226 -0
  20. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/settings.py +61 -5
  21. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/task/executor.py +1 -1
  22. vibecore-0.3.0/src/vibecore/tools/webfetch/__init__.py +7 -0
  23. vibecore-0.3.0/src/vibecore/tools/webfetch/executor.py +127 -0
  24. vibecore-0.3.0/src/vibecore/tools/webfetch/models.py +22 -0
  25. vibecore-0.3.0/src/vibecore/tools/webfetch/tools.py +46 -0
  26. vibecore-0.3.0/src/vibecore/tools/websearch/__init__.py +5 -0
  27. vibecore-0.3.0/src/vibecore/tools/websearch/base.py +27 -0
  28. vibecore-0.3.0/src/vibecore/tools/websearch/ddgs/__init__.py +5 -0
  29. vibecore-0.3.0/src/vibecore/tools/websearch/ddgs/backend.py +64 -0
  30. vibecore-0.3.0/src/vibecore/tools/websearch/executor.py +43 -0
  31. vibecore-0.3.0/src/vibecore/tools/websearch/models.py +20 -0
  32. vibecore-0.3.0/src/vibecore/tools/websearch/tools.py +49 -0
  33. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/tool_message_factory.py +24 -0
  34. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/tool_messages.py +219 -0
  35. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/tool_messages.tcss +94 -0
  36. vibecore-0.2.0a1/src/vibecore/cli.py +0 -131
  37. {vibecore-0.2.0a1 → vibecore-0.3.0}/.gitignore +0 -0
  38. {vibecore-0.2.0a1 → vibecore-0.3.0}/LICENSE +0 -0
  39. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/__init__.py +0 -0
  40. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/agents/prompts.py +0 -0
  41. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/context.py +0 -0
  42. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/handlers/__init__.py +0 -0
  43. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/main.tcss +0 -0
  44. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/mcp/__init__.py +0 -0
  45. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/mcp/manager.py +0 -0
  46. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/mcp/server_wrapper.py +0 -0
  47. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/models/__init__.py +0 -0
  48. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/models/anthropic.py +0 -0
  49. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/prompts/common_system_prompt.txt +0 -0
  50. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/py.typed +0 -0
  51. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/session/__init__.py +0 -0
  52. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/session/file_lock.py +0 -0
  53. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/session/jsonl_session.py +0 -0
  54. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/session/loader.py +0 -0
  55. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/session/path_utils.py +0 -0
  56. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/__init__.py +0 -0
  57. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/base.py +0 -0
  58. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/file/__init__.py +0 -0
  59. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/file/executor.py +0 -0
  60. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/file/tools.py +0 -0
  61. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/file/utils.py +0 -0
  62. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/__init__.py +0 -0
  63. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/backends/__init__.py +0 -0
  64. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/backends/terminal_backend.py +0 -0
  65. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/helpers.py +0 -0
  66. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/manager.py +0 -0
  67. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/python/tools.py +0 -0
  68. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/shell/__init__.py +0 -0
  69. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/shell/executor.py +0 -0
  70. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/shell/tools.py +0 -0
  71. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/task/__init__.py +0 -0
  72. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/task/tools.py +0 -0
  73. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/todo/__init__.py +0 -0
  74. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/todo/manager.py +0 -0
  75. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/todo/models.py +0 -0
  76. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/tools/todo/tools.py +0 -0
  77. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/utils/__init__.py +0 -0
  78. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/utils/text.py +0 -0
  79. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/core.py +0 -0
  80. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/core.tcss +0 -0
  81. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/expandable.py +0 -0
  82. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/expandable.tcss +0 -0
  83. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/info.py +0 -0
  84. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/info.tcss +0 -0
  85. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/messages.py +0 -0
  86. {vibecore-0.2.0a1 → vibecore-0.3.0}/src/vibecore/widgets/messages.tcss +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibecore
3
- Version: 0.2.0a1
3
+ Version: 0.3.0
4
4
  Summary: Build your own AI-powered automation tools in the terminal with this extensible agent framework
5
5
  Project-URL: Homepage, https://github.com/serialx/vibecore
6
6
  Project-URL: Repository, https://github.com/serialx/vibecore
@@ -27,6 +27,9 @@ Classifier: Topic :: Terminals
27
27
  Classifier: Topic :: Text Processing :: Linguistic
28
28
  Classifier: Typing :: Typed
29
29
  Requires-Python: >=3.11
30
+ Requires-Dist: ddgs>=9.5.4
31
+ Requires-Dist: html2text>=2024.2.26
32
+ Requires-Dist: httpx>=0.24.0
30
33
  Requires-Dist: litellm>=1.72.4
31
34
  Requires-Dist: openai-agents[litellm]>=0.2.2
32
35
  Requires-Dist: pydantic-settings>=2.10.1
@@ -65,6 +68,7 @@ Built on [Textual](https://textual.textualize.io/) and the [OpenAI Agents SDK](h
65
68
 
66
69
  ### Key Features
67
70
 
71
+ - **Flow Mode (Experimental)** - Build structured agent-based applications with programmatic conversation control
68
72
  - **AI-Powered Chat Interface** - Interact with state-of-the-art language models through an intuitive terminal interface
69
73
  - **Rich Tool Integration** - Built-in tools for file operations, shell commands, Python execution, and task management
70
74
  - **MCP Support** - Connect to external tools and services via Model Context Protocol servers
@@ -79,6 +83,26 @@ Built on [Textual](https://textual.textualize.io/) and the [OpenAI Agents SDK](h
79
83
  ### Prerequisites
80
84
 
81
85
  - Python 3.11 or higher
86
+ - (Optional) [uv](https://docs.astral.sh/uv/) for quick testing and better package management
87
+
88
+ ### Quick Test (No Installation)
89
+
90
+ Try vibecore instantly without installing it:
91
+
92
+ ```bash
93
+ # Install uv if you don't have it (optional)
94
+ curl -LsSf https://astral.sh/uv/install.sh | sh
95
+
96
+ # Configure your API key
97
+ export ANTHROPIC_API_KEY="your-api-key-here"
98
+ # or
99
+ export OPENAI_API_KEY="your-api-key-here"
100
+
101
+ # Run vibecore directly with uvx
102
+ uvx vibecore
103
+ ```
104
+
105
+ This will download and run vibecore in an isolated environment without affecting your system Python installation.
82
106
 
83
107
  ### Install from PyPI
84
108
 
@@ -136,6 +160,88 @@ Once vibecore is running, you can:
136
160
  - `/help` - Show help and keyboard shortcuts
137
161
  - `/clear` - Clear the current session and start a new one
138
162
 
163
+ ## Flow Mode (Experimental)
164
+
165
+ Flow Mode is vibecore's **key differentiator** - it transforms the framework from a chat interface into a platform for building structured agent-based applications with programmatic conversation control.
166
+
167
+ ### What is Flow Mode?
168
+
169
+ Flow Mode allows you to:
170
+ - **Define custom conversation logic** that controls how agents process user input
171
+ - **Build multi-step workflows** with defined sequences and decision points
172
+ - **Orchestrate multiple agents** with handoffs and shared context
173
+ - **Maintain conversation state** across interactions
174
+ - **Create agent-based applications** rather than just chatbots
175
+
176
+ ### Example: Simple Flow
177
+
178
+ ```python
179
+ import asyncio
180
+ from agents import Agent, Runner
181
+ from vibecore.flow import flow, UserInputFunc
182
+ from vibecore.context import VibecoreContext
183
+
184
+ # Define your agent with tools
185
+ agent = Agent[VibecoreContext](
186
+ name="Assistant",
187
+ instructions="You are a helpful assistant",
188
+ tools=[...], # Your tools here
189
+ )
190
+
191
+ # Define your conversation logic
192
+ async def logic(app, ctx: VibecoreContext, user_input: UserInputFunc):
193
+ # Get user input programmatically
194
+ user_message = await user_input("What would you like to do?")
195
+
196
+ # Process with agent
197
+ result = Runner.run_streamed(
198
+ agent,
199
+ input=user_message,
200
+ context=ctx,
201
+ session=app.session,
202
+ )
203
+
204
+ # Handle the response
205
+ app.current_worker = app.handle_streamed_response(result)
206
+ await app.current_worker.wait()
207
+
208
+ # Run the flow
209
+ async def main():
210
+ await flow(agent, logic)
211
+
212
+ if __name__ == "__main__":
213
+ asyncio.run(main())
214
+ ```
215
+
216
+ ### Example: Multi-Agent Customer Service
217
+
218
+ Flow Mode shines when building complex multi-agent systems. See `examples/customer_service.py` for a complete implementation featuring:
219
+
220
+ - **Triage Agent**: Routes requests to appropriate specialists
221
+ - **FAQ Agent**: Handles frequently asked questions
222
+ - **Booking Agent**: Manages seat reservations
223
+ - **Agent Handoffs**: Seamless transitions between agents with context preservation
224
+ - **Shared State**: Maintains customer information across the conversation
225
+
226
+ ### Key Components
227
+
228
+ - **`flow()`**: Entry point that sets up the Vibecore app with your custom logic
229
+ - **`logic()`**: Your async function that controls the conversation flow
230
+ - **`UserInputFunc`**: Provides programmatic user input collection
231
+ - **`VibecoreContext`**: Shared state across tools and agents
232
+ - **Agent Handoffs**: Transfer control between specialized agents
233
+
234
+ ### Use Cases
235
+
236
+ Flow Mode enables building:
237
+ - **Customer service systems** with routing and escalation
238
+ - **Guided workflows** for complex tasks
239
+ - **Interactive tutorials** with step-by-step guidance
240
+ - **Task automation** with human-in-the-loop controls
241
+ - **Multi-stage data processing** pipelines
242
+
243
+ The examples in the `examples/` directory are adapted from the official OpenAI Agents SDK with minimal modifications, demonstrating how easily you can build sophisticated agent applications with vibecore.
244
+
139
245
  ### Available Tools
140
246
 
141
247
  vibecore comes with powerful built-in tools:
@@ -29,6 +29,7 @@ Built on [Textual](https://textual.textualize.io/) and the [OpenAI Agents SDK](h
29
29
 
30
30
  ### Key Features
31
31
 
32
+ - **Flow Mode (Experimental)** - Build structured agent-based applications with programmatic conversation control
32
33
  - **AI-Powered Chat Interface** - Interact with state-of-the-art language models through an intuitive terminal interface
33
34
  - **Rich Tool Integration** - Built-in tools for file operations, shell commands, Python execution, and task management
34
35
  - **MCP Support** - Connect to external tools and services via Model Context Protocol servers
@@ -43,6 +44,26 @@ Built on [Textual](https://textual.textualize.io/) and the [OpenAI Agents SDK](h
43
44
  ### Prerequisites
44
45
 
45
46
  - Python 3.11 or higher
47
+ - (Optional) [uv](https://docs.astral.sh/uv/) for quick testing and better package management
48
+
49
+ ### Quick Test (No Installation)
50
+
51
+ Try vibecore instantly without installing it:
52
+
53
+ ```bash
54
+ # Install uv if you don't have it (optional)
55
+ curl -LsSf https://astral.sh/uv/install.sh | sh
56
+
57
+ # Configure your API key
58
+ export ANTHROPIC_API_KEY="your-api-key-here"
59
+ # or
60
+ export OPENAI_API_KEY="your-api-key-here"
61
+
62
+ # Run vibecore directly with uvx
63
+ uvx vibecore
64
+ ```
65
+
66
+ This will download and run vibecore in an isolated environment without affecting your system Python installation.
46
67
 
47
68
  ### Install from PyPI
48
69
 
@@ -100,6 +121,88 @@ Once vibecore is running, you can:
100
121
  - `/help` - Show help and keyboard shortcuts
101
122
  - `/clear` - Clear the current session and start a new one
102
123
 
124
+ ## Flow Mode (Experimental)
125
+
126
+ Flow Mode is vibecore's **key differentiator** - it transforms the framework from a chat interface into a platform for building structured agent-based applications with programmatic conversation control.
127
+
128
+ ### What is Flow Mode?
129
+
130
+ Flow Mode allows you to:
131
+ - **Define custom conversation logic** that controls how agents process user input
132
+ - **Build multi-step workflows** with defined sequences and decision points
133
+ - **Orchestrate multiple agents** with handoffs and shared context
134
+ - **Maintain conversation state** across interactions
135
+ - **Create agent-based applications** rather than just chatbots
136
+
137
+ ### Example: Simple Flow
138
+
139
+ ```python
140
+ import asyncio
141
+ from agents import Agent, Runner
142
+ from vibecore.flow import flow, UserInputFunc
143
+ from vibecore.context import VibecoreContext
144
+
145
+ # Define your agent with tools
146
+ agent = Agent[VibecoreContext](
147
+ name="Assistant",
148
+ instructions="You are a helpful assistant",
149
+ tools=[...], # Your tools here
150
+ )
151
+
152
+ # Define your conversation logic
153
+ async def logic(app, ctx: VibecoreContext, user_input: UserInputFunc):
154
+ # Get user input programmatically
155
+ user_message = await user_input("What would you like to do?")
156
+
157
+ # Process with agent
158
+ result = Runner.run_streamed(
159
+ agent,
160
+ input=user_message,
161
+ context=ctx,
162
+ session=app.session,
163
+ )
164
+
165
+ # Handle the response
166
+ app.current_worker = app.handle_streamed_response(result)
167
+ await app.current_worker.wait()
168
+
169
+ # Run the flow
170
+ async def main():
171
+ await flow(agent, logic)
172
+
173
+ if __name__ == "__main__":
174
+ asyncio.run(main())
175
+ ```
176
+
177
+ ### Example: Multi-Agent Customer Service
178
+
179
+ Flow Mode shines when building complex multi-agent systems. See `examples/customer_service.py` for a complete implementation featuring:
180
+
181
+ - **Triage Agent**: Routes requests to appropriate specialists
182
+ - **FAQ Agent**: Handles frequently asked questions
183
+ - **Booking Agent**: Manages seat reservations
184
+ - **Agent Handoffs**: Seamless transitions between agents with context preservation
185
+ - **Shared State**: Maintains customer information across the conversation
186
+
187
+ ### Key Components
188
+
189
+ - **`flow()`**: Entry point that sets up the Vibecore app with your custom logic
190
+ - **`logic()`**: Your async function that controls the conversation flow
191
+ - **`UserInputFunc`**: Provides programmatic user input collection
192
+ - **`VibecoreContext`**: Shared state across tools and agents
193
+ - **Agent Handoffs**: Transfer control between specialized agents
194
+
195
+ ### Use Cases
196
+
197
+ Flow Mode enables building:
198
+ - **Customer service systems** with routing and escalation
199
+ - **Guided workflows** for complex tasks
200
+ - **Interactive tutorials** with step-by-step guidance
201
+ - **Task automation** with human-in-the-loop controls
202
+ - **Multi-stage data processing** pipelines
203
+
204
+ The examples in the `examples/` directory are adapted from the official OpenAI Agents SDK with minimal modifications, demonstrating how easily you can build sophisticated agent applications with vibecore.
205
+
103
206
  ### Available Tools
104
207
 
105
208
  vibecore comes with powerful built-in tools:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vibecore"
3
- version = "0.2.0a1"
3
+ version = "0.3.0"
4
4
  description = "Build your own AI-powered automation tools in the terminal with this extensible agent framework"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -44,6 +44,9 @@ classifiers = [
44
44
  "Typing :: Typed",
45
45
  ]
46
46
  dependencies = [
47
+ "ddgs>=9.5.4",
48
+ "html2text>=2024.2.26",
49
+ "httpx>=0.24.0",
47
50
  "litellm>=1.72.4",
48
51
  "openai-agents[litellm]>=0.2.2",
49
52
  "pydantic-settings>=2.10.1",
@@ -59,7 +62,7 @@ dependencies = [
59
62
  "Documentation" = "https://github.com/serialx/vibecore#readme"
60
63
 
61
64
  [project.scripts]
62
- vibecore = "vibecore.cli:main"
65
+ vibecore = "vibecore.cli:cli_main"
63
66
 
64
67
  [[tool.uv.index]]
65
68
  name = "testpypi"
@@ -1,8 +1,7 @@
1
1
  from typing import TYPE_CHECKING
2
2
 
3
- from agents import Agent, ModelSettings
3
+ from agents import Agent
4
4
  from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
5
- from openai.types import Reasoning
6
5
 
7
6
  from vibecore.context import VibecoreContext
8
7
  from vibecore.settings import settings
@@ -11,6 +10,8 @@ from vibecore.tools.python.tools import execute_python
11
10
  from vibecore.tools.shell.tools import bash, glob, grep, ls
12
11
  from vibecore.tools.task.tools import task
13
12
  from vibecore.tools.todo.tools import todo_read, todo_write
13
+ from vibecore.tools.webfetch.tools import webfetch
14
+ from vibecore.tools.websearch.tools import websearch
14
15
 
15
16
  from .prompts import COMMON_PROMPT
16
17
 
@@ -50,26 +51,20 @@ def create_default_agent(mcp_servers: list["MCPServer"] | None = None) -> Agent[
50
51
  grep,
51
52
  ls,
52
53
  task,
54
+ websearch,
55
+ webfetch,
53
56
  ]
54
57
  instructions = INSTRUCTIONS
55
58
 
56
59
  instructions = prompt_with_handoff_instructions(instructions)
57
60
 
58
- # Configure reasoning based on settings
59
- reasoning_config = Reasoning(summary="auto")
60
- if settings.reasoning_effort is not None:
61
- reasoning_config = Reasoning(effort=settings.reasoning_effort, summary="auto")
62
-
63
61
  return Agent[VibecoreContext](
64
62
  name="Vibecore Agent",
65
63
  handoff_description="A versatile general-purpose assistant",
66
64
  instructions=instructions,
67
65
  tools=tools,
68
66
  model=settings.model,
69
- model_settings=ModelSettings(
70
- include_usage=True, # Ensure token usage is tracked in streaming mode
71
- reasoning=reasoning_config,
72
- ),
67
+ model_settings=settings.default_model_settings,
73
68
  handoffs=[],
74
69
  mcp_servers=mcp_servers or [],
75
70
  )
@@ -1,8 +1,7 @@
1
1
  """Task-specific agent configuration for executing delegated tasks."""
2
2
 
3
- from agents import Agent, ModelSettings
3
+ from agents import Agent
4
4
  from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
5
- from openai.types import Reasoning
6
5
 
7
6
  from vibecore.context import VibecoreContext
8
7
  from vibecore.settings import settings
@@ -58,9 +57,6 @@ def create_task_agent(prompt: str) -> Agent[VibecoreContext]:
58
57
  instructions=instructions,
59
58
  tools=tools,
60
59
  model=settings.model,
61
- model_settings=ModelSettings(
62
- include_usage=True, # Ensure token usage is tracked in streaming mode
63
- reasoning=Reasoning(summary="auto"),
64
- ),
60
+ model_settings=settings.default_model_settings,
65
61
  handoffs=[],
66
62
  )
@@ -0,0 +1,15 @@
1
+ """Anthropic Pro/Max authentication module."""
2
+
3
+ from vibecore.auth.config import ANTHROPIC_CONFIG
4
+ from vibecore.auth.manager import AnthropicAuthManager
5
+ from vibecore.auth.models import AnthropicAuth, ApiKeyCredentials, OAuthCredentials
6
+ from vibecore.auth.storage import SecureAuthStorage
7
+
8
+ __all__ = [
9
+ "ANTHROPIC_CONFIG",
10
+ "AnthropicAuth",
11
+ "AnthropicAuthManager",
12
+ "ApiKeyCredentials",
13
+ "OAuthCredentials",
14
+ "SecureAuthStorage",
15
+ ]
@@ -0,0 +1,38 @@
1
+ """Configuration constants for Anthropic authentication."""
2
+
3
+ from typing import Final
4
+
5
+
6
+ class AnthropicConfig:
7
+ """Configuration for Anthropic OAuth and API."""
8
+
9
+ # OAuth Client Configuration
10
+ OAUTH_CLIENT_ID: Final[str] = "9d1c250a-e61b-44d9-88ed-5944d1962f5e"
11
+ OAUTH_SCOPES: Final[str] = "org:create_api_key user:profile user:inference"
12
+ OAUTH_REDIRECT_URI: Final[str] = "https://console.anthropic.com/oauth/code/callback"
13
+ OAUTH_RESPONSE_TYPE: Final[str] = "code"
14
+ OAUTH_CODE_CHALLENGE_METHOD: Final[str] = "S256"
15
+
16
+ # API Endpoints
17
+ CLAUDE_AI_AUTHORIZE: Final[str] = "https://claude.ai/oauth/authorize"
18
+ CONSOLE_AUTHORIZE: Final[str] = "https://console.anthropic.com/oauth/authorize"
19
+ TOKEN_EXCHANGE: Final[str] = "https://console.anthropic.com/v1/oauth/token"
20
+ API_BASE: Final[str] = "https://api.anthropic.com"
21
+ MESSAGES: Final[str] = "https://api.anthropic.com/v1/messages"
22
+
23
+ # Beta Headers (Critical for Claude Code spoofing)
24
+ BETA_OAUTH: Final[str] = "oauth-2025-04-20"
25
+ BETA_CLAUDE_CODE: Final[str] = "claude-code-20250219" # CRITICAL: Identifies as Claude Code
26
+ BETA_INTERLEAVED_THINKING: Final[str] = "interleaved-thinking-2025-05-14"
27
+ BETA_FINE_GRAINED_STREAMING: Final[str] = "fine-grained-tool-streaming-2025-05-14"
28
+
29
+ # Token Management
30
+ TOKEN_REFRESH_BUFFER_SECONDS: Final[int] = 300 # Refresh 5 minutes before expiry
31
+ TOKEN_MAX_RETRY_ATTEMPTS: Final[int] = 3
32
+ TOKEN_RETRY_DELAY_MS: Final[int] = 1000
33
+
34
+ # Claude Code Identity
35
+ CLAUDE_CODE_IDENTITY: Final[str] = "You are Claude Code, Anthropic's official CLI for Claude."
36
+
37
+
38
+ ANTHROPIC_CONFIG = AnthropicConfig()
@@ -0,0 +1,141 @@
1
+ """HTTP request interceptor for Claude Code spoofing."""
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+ from httpx import URL
7
+
8
+ from vibecore.auth.config import ANTHROPIC_CONFIG
9
+ from vibecore.auth.storage import SecureAuthStorage
10
+ from vibecore.auth.token_manager import TokenRefreshManager
11
+
12
+
13
+ class AnthropicRequestInterceptor:
14
+ """Intercepts and modifies Anthropic API requests."""
15
+
16
+ def __init__(self, storage: SecureAuthStorage):
17
+ """
18
+ Initialize request interceptor.
19
+
20
+ Args:
21
+ storage: Secure storage for credentials.
22
+ """
23
+ self.storage = storage
24
+ self.token_manager = TokenRefreshManager(storage)
25
+
26
+ async def intercept_request(self, url: str, headers: dict[str, str] | None = None, **kwargs: Any) -> dict[str, Any]:
27
+ """
28
+ Intercept and modify request for Anthropic API.
29
+
30
+ Args:
31
+ url: Request URL.
32
+ headers: Request headers.
33
+ **kwargs: Additional request parameters.
34
+
35
+ Returns:
36
+ Modified request parameters.
37
+ """
38
+ auth = await self.storage.load("anthropic")
39
+
40
+ if not auth:
41
+ raise ValueError("Not authenticated with Anthropic")
42
+
43
+ # Prepare headers
44
+ headers = {} if headers is None else headers.copy()
45
+
46
+ if auth.type == "oauth": # OAuth auth
47
+ await self._configure_oauth_headers(headers)
48
+ else: # API key auth
49
+ self._configure_api_key_headers(headers, auth.key) # type: ignore
50
+
51
+ # Apply Claude Code spoofing headers
52
+ self._apply_claude_code_headers(headers)
53
+
54
+ # Return modified request parameters
55
+ return {**kwargs, "headers": headers}
56
+
57
+ async def _configure_oauth_headers(self, headers: dict[str, str]) -> None:
58
+ """Configure headers for OAuth authentication."""
59
+ # Get valid access token (handles refresh automatically)
60
+ access_token = await self.token_manager.get_valid_token()
61
+
62
+ # Remove any API key headers (OAuth takes precedence)
63
+ headers.pop("x-api-key", None)
64
+ headers.pop("X-Api-Key", None)
65
+ headers.pop("anthropic-api-key", None)
66
+
67
+ # Set OAuth bearer token
68
+ headers["Authorization"] = f"Bearer {access_token}"
69
+
70
+ def _configure_api_key_headers(self, headers: dict[str, str], api_key: str) -> None:
71
+ """Configure headers for API key authentication."""
72
+ # Remove OAuth headers if present
73
+ headers.pop("Authorization", None)
74
+
75
+ # Set API key
76
+ headers["x-api-key"] = api_key
77
+
78
+ def _apply_claude_code_headers(self, headers: dict[str, str]) -> None:
79
+ """Apply Claude Code spoofing headers."""
80
+ # Build beta features header
81
+ beta_features = [
82
+ ANTHROPIC_CONFIG.BETA_OAUTH,
83
+ ANTHROPIC_CONFIG.BETA_CLAUDE_CODE, # Critical for spoofing
84
+ ANTHROPIC_CONFIG.BETA_INTERLEAVED_THINKING,
85
+ # ANTHROPIC_CONFIG.BETA_FINE_GRAINED_STREAMING,
86
+ ]
87
+
88
+ # Set the beta header (this is what makes Anthropic think we're Claude Code)
89
+ headers["anthropic-beta"] = ",".join(beta_features)
90
+
91
+ # Set additional headers that Claude Code uses
92
+ headers["anthropic-version"] = "2023-06-01"
93
+ headers.setdefault("accept", "application/json")
94
+
95
+ # Add Claude Code specific headers
96
+ headers["user-agent"] = "Claude-Code/1.0"
97
+ headers["x-client-id"] = ANTHROPIC_CONFIG.OAUTH_CLIENT_ID
98
+
99
+ # Ensure content-type is set for POST requests
100
+ headers.setdefault("content-type", "application/json")
101
+
102
+
103
+ class GlobalAnthropicInterceptor:
104
+ """Global interceptor for automatic Anthropic request modification."""
105
+
106
+ def __init__(self, storage: SecureAuthStorage):
107
+ """
108
+ Initialize global interceptor.
109
+
110
+ Args:
111
+ storage: Secure storage for credentials.
112
+ """
113
+ self.interceptor = AnthropicRequestInterceptor(storage)
114
+ self.original_client_class = httpx.AsyncClient
115
+
116
+ def install(self) -> None:
117
+ """Install global request interception."""
118
+ interceptor = self.interceptor
119
+
120
+ class InterceptedAsyncClient(httpx.AsyncClient):
121
+ """Custom AsyncClient that intercepts Anthropic requests."""
122
+
123
+ async def request(self, method: str, url: URL | str, **kwargs: Any) -> httpx.Response:
124
+ """Override request method to intercept Anthropic API calls."""
125
+ # Convert URL to string if needed
126
+ url_str = str(url)
127
+
128
+ # Check if this is an Anthropic API request
129
+ if "anthropic.com" in url_str or "claude.ai" in url_str:
130
+ # Intercept and modify request
131
+ kwargs = await interceptor.intercept_request(url_str, **kwargs)
132
+
133
+ # Call original request method
134
+ return await super().request(method, url, **kwargs)
135
+
136
+ # Replace httpx.AsyncClient globally
137
+ httpx.AsyncClient = InterceptedAsyncClient # type: ignore
138
+
139
+ def uninstall(self) -> None:
140
+ """Uninstall global request interception."""
141
+ httpx.AsyncClient = self.original_client_class # type: ignore