EvoScientist 0.0.1.dev2__py3-none-any.whl → 0.0.1.dev4__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.
@@ -13,34 +13,47 @@ Usage:
13
13
  ...
14
14
  """
15
15
 
16
- import os
17
16
  from datetime import datetime
18
17
  from pathlib import Path
19
18
 
20
19
  from deepagents import create_deep_agent
21
20
  from deepagents.backends import FilesystemBackend, CompositeBackend
22
- from langchain.chat_models import init_chat_model
23
21
 
24
22
  from .backends import CustomSandboxBackend, MergedReadOnlyBackend
25
- from .middleware import create_skills_middleware
23
+ from .config import get_effective_config, apply_config_to_env
24
+ from .llm import get_chat_model
25
+ from .middleware import create_skills_middleware, create_memory_middleware
26
26
  from .prompts import RESEARCHER_INSTRUCTIONS, get_system_prompt
27
27
  from .utils import load_subagents
28
- from .tools import tavily_search, think_tool
28
+ from .tools import tavily_search, think_tool, skill_manager
29
+ from .paths import (
30
+ ensure_dirs,
31
+ default_workspace_dir,
32
+ MEMORY_DIR as _MEMORY_DIR_PATH,
33
+ USER_SKILLS_DIR as _USER_SKILLS_DIR_PATH,
34
+ )
29
35
 
30
36
  # =============================================================================
31
37
  # Configuration
32
38
  # =============================================================================
33
39
 
40
+ # Load configuration from file/env/defaults
41
+ _config = get_effective_config()
42
+ apply_config_to_env(_config)
43
+
34
44
  # Backend mode: "sandbox" (with execute) or "filesystem" (read/write only)
35
45
  BACKEND_MODE = "sandbox"
36
46
 
37
- # Research limits
38
- MAX_CONCURRENT = 3 # Max parallel sub-agents
39
- MAX_ITERATIONS = 3 # Max delegation rounds
47
+ # Research limits (from config)
48
+ MAX_CONCURRENT = _config.max_concurrent
49
+ MAX_ITERATIONS = _config.max_iterations
40
50
 
41
51
  # Workspace settings
42
- WORKSPACE_DIR = "./workspace/"
52
+ ensure_dirs()
53
+ WORKSPACE_DIR = str(default_workspace_dir())
54
+ MEMORY_DIR = str(_MEMORY_DIR_PATH) # Shared across sessions (not per-session)
43
55
  SKILLS_DIR = str(Path(__file__).parent / "skills")
56
+ USER_SKILLS_DIR = str(_USER_SKILLS_DIR_PATH)
44
57
  SUBAGENTS_CONFIG = Path(__file__).parent / "subagent.yaml"
45
58
 
46
59
  # =============================================================================
@@ -56,10 +69,10 @@ SYSTEM_PROMPT = get_system_prompt(
56
69
  max_iterations=MAX_ITERATIONS,
57
70
  )
58
71
 
59
- # Initialize chat model
60
- chat_model = init_chat_model(
61
- model="claude-sonnet-4-5-20250929",
62
- model_provider="anthropic",
72
+ # Initialize chat model using the LLM module (respects config settings)
73
+ chat_model = get_chat_model(
74
+ model=_config.model,
75
+ provider=_config.provider,
63
76
  # thinking={"type": "enabled", "budget_tokens": 2000},
64
77
  )
65
78
 
@@ -76,16 +89,25 @@ else:
76
89
  virtual_mode=True,
77
90
  )
78
91
 
79
- # Skills backend: merge user-installed (workspace) and system (package) skills
92
+ # Skills backend: merge user-installed (./skills/) and system (package) skills
80
93
  _skills_backend = MergedReadOnlyBackend(
81
- primary_dir=str(Path(WORKSPACE_DIR) / "skills"), # user-installed, takes priority
94
+ primary_dir=USER_SKILLS_DIR, # user-installed, takes priority
82
95
  secondary_dir=SKILLS_DIR, # package built-in, fallback
83
96
  )
84
97
 
85
- # Composite backend: workspace as default, skills mounted at /skills/
98
+ # Memory backend: persistent filesystem for long-term memory (shared across sessions)
99
+ _memory_backend = FilesystemBackend(
100
+ root_dir=MEMORY_DIR,
101
+ virtual_mode=True,
102
+ )
103
+
104
+ # Composite backend: workspace as default, skills and memory mounted
86
105
  backend = CompositeBackend(
87
106
  default=_workspace_backend,
88
- routes={"/skills/": _skills_backend},
107
+ routes={
108
+ "/skills/": _skills_backend,
109
+ "/memory/": _memory_backend,
110
+ },
89
111
  )
90
112
 
91
113
  tool_registry = {
@@ -107,10 +129,13 @@ subagents = load_subagents(
107
129
  _AGENT_KWARGS = dict(
108
130
  name="EvoScientist",
109
131
  model=chat_model,
110
- tools=[think_tool],
132
+ tools=[think_tool, skill_manager],
111
133
  backend=backend,
112
134
  subagents=subagents,
113
- middleware=[create_skills_middleware(SKILLS_DIR, WORKSPACE_DIR)],
135
+ middleware=[
136
+ create_memory_middleware(MEMORY_DIR, extraction_model=chat_model),
137
+ create_skills_middleware(SKILLS_DIR, user_skills_dir=USER_SKILLS_DIR),
138
+ ],
114
139
  system_prompt=SYSTEM_PROMPT,
115
140
  )
116
141
 
@@ -124,7 +149,7 @@ def create_cli_agent(workspace_dir: str | None = None):
124
149
  Args:
125
150
  workspace_dir: Optional per-session workspace directory. If provided,
126
151
  creates a fresh backend rooted at this path. If None, uses the
127
- module-level default backend (./workspace/).
152
+ module-level default backend (./workspace).
128
153
  """
129
154
  from langgraph.checkpoint.memory import InMemorySaver # type: ignore[import-untyped]
130
155
 
@@ -135,14 +160,25 @@ def create_cli_agent(workspace_dir: str | None = None):
135
160
  timeout=300,
136
161
  )
137
162
  sk_backend = MergedReadOnlyBackend(
138
- primary_dir=str(Path(workspace_dir) / "skills"),
163
+ primary_dir=USER_SKILLS_DIR,
139
164
  secondary_dir=SKILLS_DIR,
140
165
  )
166
+ # Memory always uses SHARED directory (not per-session) for cross-session persistence
167
+ mem_backend = FilesystemBackend(
168
+ root_dir=MEMORY_DIR,
169
+ virtual_mode=True,
170
+ )
141
171
  be = CompositeBackend(
142
172
  default=ws_backend,
143
- routes={"/skills/": sk_backend},
173
+ routes={
174
+ "/skills/": sk_backend,
175
+ "/memory/": mem_backend,
176
+ },
144
177
  )
145
- mw = [create_skills_middleware(SKILLS_DIR, workspace_dir)]
178
+ mw = [
179
+ create_memory_middleware(MEMORY_DIR, extraction_model=chat_model),
180
+ create_skills_middleware(SKILLS_DIR, user_skills_dir=USER_SKILLS_DIR),
181
+ ]
146
182
  kwargs = dict(
147
183
  _AGENT_KWARGS,
148
184
  backend=be,
EvoScientist/__init__.py CHANGED
@@ -1,6 +1,14 @@
1
1
  """EvoScientist Agent — AI-powered research & code execution."""
2
2
 
3
3
  from .backends import CustomSandboxBackend, ReadOnlyFilesystemBackend
4
+ from .config import (
5
+ EvoScientistConfig,
6
+ load_config,
7
+ save_config,
8
+ get_effective_config,
9
+ get_config_path,
10
+ )
11
+ from .llm import get_chat_model, MODELS, list_models, DEFAULT_MODEL
4
12
  from .middleware import create_skills_middleware
5
13
  from .prompts import get_system_prompt, RESEARCHER_INSTRUCTIONS
6
14
  from .tools import tavily_search, think_tool
@@ -13,6 +21,17 @@ __all__ = [
13
21
  # Backends
14
22
  "CustomSandboxBackend",
15
23
  "ReadOnlyFilesystemBackend",
24
+ # Configuration
25
+ "EvoScientistConfig",
26
+ "load_config",
27
+ "save_config",
28
+ "get_effective_config",
29
+ "get_config_path",
30
+ # LLM
31
+ "get_chat_model",
32
+ "MODELS",
33
+ "list_models",
34
+ "DEFAULT_MODEL",
16
35
  # Middleware
17
36
  "create_skills_middleware",
18
37
  # Prompts