akseljoonas HF Staff commited on
Commit
4501765
·
1 Parent(s): 4a5df81

Refactor approval handling and enhance markdown table styles

Browse files
agent/core/agent_loop.py CHANGED
@@ -169,6 +169,30 @@ def _is_transient_error(error: Exception) -> bool:
169
  return any(pattern in err_str for pattern in transient_patterns)
170
 
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  async def _compact_and_notify(session: Session) -> None:
173
  """Run compaction and send event if context was reduced."""
174
  old_length = session.context_manager.context_length
@@ -559,7 +583,7 @@ class Handlers:
559
 
560
  # If no tool calls, add assistant message and we're done
561
  if not tool_calls:
562
- logger.warning(
563
  "Agent loop ending: no tool calls. "
564
  "finish_reason=%s, token_count=%d, "
565
  "context_length=%d, max_context=%d, "
@@ -573,20 +597,6 @@ class Handlers:
573
  max_iterations,
574
  (content or "")[:500],
575
  )
576
- await session.send_event(
577
- Event(
578
- event_type="tool_log",
579
- data={
580
- "tool": "system",
581
- "log": (
582
- f"Loop exit: no tool calls. "
583
- f"finish_reason={finish_reason}, "
584
- f"tokens={token_count}/{session.context_manager.max_context}, "
585
- f"iter={iteration}/{max_iterations}"
586
- ),
587
- },
588
- )
589
- )
590
  if content:
591
  assistant_msg = Message(role="assistant", content=content)
592
  session.context_manager.add_message(assistant_msg, token_count)
@@ -802,10 +812,14 @@ class Handlers:
802
  except Exception as e:
803
  import traceback
804
 
 
 
 
 
805
  await session.send_event(
806
  Event(
807
  event_type="error",
808
- data={"error": str(e) + "\n" + traceback.format_exc()},
809
  )
810
  )
811
  errored = True
@@ -1156,7 +1170,10 @@ async def submission_loop(
1156
  async with tool_router:
1157
  # Emit ready event after initialization
1158
  await session.send_event(
1159
- Event(event_type="ready", data={"message": "Agent initialized"})
 
 
 
1160
  )
1161
 
1162
  while session.is_running:
 
169
  return any(pattern in err_str for pattern in transient_patterns)
170
 
171
 
172
+ def _friendly_error_message(error: Exception) -> str | None:
173
+ """Return a user-friendly message for known error types, or None to fall back to traceback."""
174
+ err_str = str(error).lower()
175
+
176
+ if "authentication" in err_str or "unauthorized" in err_str or "invalid x-api-key" in err_str:
177
+ return (
178
+ "Authentication failed — your API key is missing or invalid.\n\n"
179
+ "To fix this, set the API key for your model provider:\n"
180
+ " • Anthropic: export ANTHROPIC_API_KEY=sk-...\n"
181
+ " • OpenAI: export OPENAI_API_KEY=sk-...\n"
182
+ " • HF Router: export HF_TOKEN=hf_...\n\n"
183
+ "You can also add it to a .env file in the project root.\n"
184
+ "To switch models, use the /model command."
185
+ )
186
+
187
+ if "insufficient" in err_str and "credit" in err_str:
188
+ return (
189
+ "Insufficient API credits. Please check your account balance "
190
+ "at your model provider's dashboard."
191
+ )
192
+
193
+ return None
194
+
195
+
196
  async def _compact_and_notify(session: Session) -> None:
197
  """Run compaction and send event if context was reduced."""
198
  old_length = session.context_manager.context_length
 
583
 
584
  # If no tool calls, add assistant message and we're done
585
  if not tool_calls:
586
+ logger.debug(
587
  "Agent loop ending: no tool calls. "
588
  "finish_reason=%s, token_count=%d, "
589
  "context_length=%d, max_context=%d, "
 
597
  max_iterations,
598
  (content or "")[:500],
599
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
600
  if content:
601
  assistant_msg = Message(role="assistant", content=content)
602
  session.context_manager.add_message(assistant_msg, token_count)
 
812
  except Exception as e:
813
  import traceback
814
 
815
+ error_msg = _friendly_error_message(e)
816
+ if error_msg is None:
817
+ error_msg = str(e) + "\n" + traceback.format_exc()
818
+
819
  await session.send_event(
820
  Event(
821
  event_type="error",
822
+ data={"error": error_msg},
823
  )
824
  )
825
  errored = True
 
1170
  async with tool_router:
1171
  # Emit ready event after initialization
1172
  await session.send_event(
1173
+ Event(event_type="ready", data={
1174
+ "message": "Agent initialized",
1175
+ "tool_count": len(tool_router.tools),
1176
+ })
1177
  )
1178
 
1179
  while session.is_running:
agent/main.py CHANGED
@@ -251,7 +251,8 @@ async def event_listener(
251
  event = await event_queue.get()
252
 
253
  if event.event_type == "ready":
254
- print_init_done()
 
255
  ready_event.set()
256
  elif event.event_type == "assistant_message":
257
  shimmer.stop()
@@ -711,8 +712,6 @@ async def main():
711
  # Clear screen
712
  os.system("clear" if os.name != "nt" else "cls")
713
 
714
- print_banner()
715
-
716
  # Create prompt session for input (needed early for token prompt)
717
  prompt_session = PromptSession()
718
 
@@ -721,6 +720,16 @@ async def main():
721
  if not hf_token:
722
  hf_token = await _prompt_and_save_hf_token(prompt_session)
723
 
 
 
 
 
 
 
 
 
 
 
724
  # Create queues for communication
725
  submission_queue = asyncio.Queue()
726
  event_queue = asyncio.Queue()
 
251
  event = await event_queue.get()
252
 
253
  if event.event_type == "ready":
254
+ tool_count = event.data.get("tool_count", 0) if event.data else 0
255
+ print_init_done(tool_count=tool_count)
256
  ready_event.set()
257
  elif event.event_type == "assistant_message":
258
  shimmer.stop()
 
712
  # Clear screen
713
  os.system("clear" if os.name != "nt" else "cls")
714
 
 
 
715
  # Create prompt session for input (needed early for token prompt)
716
  prompt_session = PromptSession()
717
 
 
720
  if not hf_token:
721
  hf_token = await _prompt_and_save_hf_token(prompt_session)
722
 
723
+ # Resolve username for banner
724
+ hf_user = None
725
+ try:
726
+ from huggingface_hub import HfApi
727
+ hf_user = HfApi(token=hf_token).whoami().get("name")
728
+ except Exception:
729
+ pass
730
+
731
+ print_banner(hf_user=hf_user)
732
+
733
  # Create queues for communication
734
  submission_queue = asyncio.Queue()
735
  event_queue = asyncio.Queue()
agent/utils/braille.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Braille-character canvas for high-resolution terminal graphics.
2
+
3
+ Each terminal cell maps to a 2x4 dot grid using Unicode braille characters
4
+ (U+2800–U+28FF), giving 2× horizontal and 4× vertical resolution.
5
+ """
6
+
7
+ # Braille dot positions: (0,0) (1,0) dots 1,4
8
+ # (0,1) (1,1) dots 2,5
9
+ # (0,2) (1,2) dots 3,6
10
+ # (0,3) (1,3) dots 7,8
11
+ _DOT_MAP = (
12
+ (0x01, 0x08),
13
+ (0x02, 0x10),
14
+ (0x04, 0x20),
15
+ (0x40, 0x80),
16
+ )
17
+
18
+
19
+ class BrailleCanvas:
20
+ """A pixel canvas that renders to braille characters."""
21
+
22
+ def __init__(self, term_width: int, term_height: int):
23
+ self.term_width = term_width
24
+ self.term_height = term_height
25
+ self.pixel_width = term_width * 2
26
+ self.pixel_height = term_height * 4
27
+ self._buf = bytearray(term_width * term_height)
28
+
29
+ def clear(self) -> None:
30
+ for i in range(len(self._buf)):
31
+ self._buf[i] = 0
32
+
33
+ def set_pixel(self, x: int, y: int) -> None:
34
+ if 0 <= x < self.pixel_width and 0 <= y < self.pixel_height:
35
+ cx, rx = divmod(x, 2)
36
+ cy, ry = divmod(y, 4)
37
+ self._buf[cy * self.term_width + cx] |= _DOT_MAP[ry][rx]
38
+
39
+ def render(self) -> list[str]:
40
+ lines = []
41
+ for row in range(self.term_height):
42
+ offset = row * self.term_width
43
+ line = "".join(
44
+ chr(0x2800 + self._buf[offset + col])
45
+ for col in range(self.term_width)
46
+ )
47
+ lines.append(line)
48
+ return lines
49
+
50
+
51
+ # ── Bitmap font (5×7 uppercase + digits) ──────────────────────────────
52
+
53
+ _FONT: dict[str, list[str]] = {}
54
+
55
+ def _define_font() -> None:
56
+ """Define a simple 5×7 bitmap font for uppercase ASCII."""
57
+ glyphs = {
58
+ "A": [" ## ", "# #", "# #", "####", "# #", "# #", "# #"],
59
+ "B": ["### ", "# #", "# #", "### ", "# #", "# #", "### "],
60
+ "C": [" ## ", "# #", "# ", "# ", "# ", "# #", " ## "],
61
+ "D": ["### ", "# #", "# #", "# #", "# #", "# #", "### "],
62
+ "E": ["####", "# ", "# ", "### ", "# ", "# ", "####"],
63
+ "F": ["####", "# ", "# ", "### ", "# ", "# ", "# "],
64
+ "G": [" ## ", "# #", "# ", "# ##", "# #", "# #", " ###"],
65
+ "H": ["# #", "# #", "# #", "####", "# #", "# #", "# #"],
66
+ "I": ["###", " # ", " # ", " # ", " # ", " # ", "###"],
67
+ "J": [" ##", " # ", " # ", " # ", " # ", "# # ", " # "],
68
+ "K": ["# #", "# # ", "## ", "## ", "# # ", "# #", "# #"],
69
+ "L": ["# ", "# ", "# ", "# ", "# ", "# ", "####"],
70
+ "M": ["# #", "## ##", "# # #", "# # #", "# #", "# #", "# #"],
71
+ "N": ["# #", "## #", "## #", "# ##", "# ##", "# #", "# #"],
72
+ "O": [" ## ", "# #", "# #", "# #", "# #", "# #", " ## "],
73
+ "P": ["### ", "# #", "# #", "### ", "# ", "# ", "# "],
74
+ "Q": [" ## ", "# #", "# #", "# #", "# ##", "# #", " ## "],
75
+ "R": ["### ", "# #", "# #", "### ", "# # ", "# #", "# #"],
76
+ "S": [" ## ", "# #", "# ", " ## ", " #", "# #", " ## "],
77
+ "T": ["#####", " # ", " # ", " # ", " # ", " # ", " # "],
78
+ "U": ["# #", "# #", "# #", "# #", "# #", "# #", " ## "],
79
+ "V": ["# #", "# #", "# #", " # # ", " # # ", " # ", " # "],
80
+ "W": ["# #", "# #", "# #", "# # #", "# # #", "## ##", "# #"],
81
+ "X": ["# #", "# #", " ## ", " ## ", " ## ", "# #", "# #"],
82
+ "Y": ["# #", "# #", " # # ", " # ", " # ", " # ", " # "],
83
+ "Z": ["####", " #", " # ", " # ", "# ", "# ", "####"],
84
+ " ": [" ", " ", " ", " ", " ", " ", " "],
85
+ "0": [" ## ", "# #", "# #", "# #", "# #", "# #", " ## "],
86
+ "1": [" # ", "## ", " # ", " # ", " # ", " # ", "###"],
87
+ "2": [" ## ", "# #", " #", " # ", " # ", "# ", "####"],
88
+ "3": [" ## ", "# #", " #", " ## ", " #", "# #", " ## "],
89
+ "4": ["# #", "# #", "# #", "####", " #", " #", " #"],
90
+ "5": ["####", "# ", "### ", " #", " #", "# #", " ## "],
91
+ "6": [" ## ", "# ", "### ", "# #", "# #", "# #", " ## "],
92
+ "7": ["####", " #", " # ", " # ", " # ", " # ", " # "],
93
+ "8": [" ## ", "# #", "# #", " ## ", "# #", "# #", " ## "],
94
+ "9": [" ## ", "# #", "# #", " ###", " #", " #", " ## "],
95
+ }
96
+ _FONT.update(glyphs)
97
+
98
+
99
+ _define_font()
100
+
101
+
102
+ def text_to_pixels(text: str, scale: int = 1) -> list[tuple[int, int]]:
103
+ """Convert text string to a list of (x, y) pixel positions using bitmap font."""
104
+ pixels = []
105
+ cursor_x = 0
106
+ for ch in text.upper():
107
+ glyph = _FONT.get(ch)
108
+ if glyph is None:
109
+ cursor_x += 4 * scale
110
+ continue
111
+ for row_idx, row in enumerate(glyph):
112
+ for col_idx, cell in enumerate(row):
113
+ if cell == "#":
114
+ for sy in range(scale):
115
+ for sx in range(scale):
116
+ pixels.append((cursor_x + col_idx * scale + sx,
117
+ row_idx * scale + sy))
118
+ glyph_width = max(len(r) for r in glyph)
119
+ cursor_x += (glyph_width + 1) * scale
120
+ return pixels
agent/utils/terminal_display.py CHANGED
@@ -8,7 +8,7 @@ from rich.panel import Panel
8
  from rich.theme import Theme
9
 
10
  _THEME = Theme({
11
- "tool.name": "bold cyan",
12
  "tool.args": "dim",
13
  "tool.ok": "dim green",
14
  "tool.fail": "dim red",
@@ -28,31 +28,75 @@ def get_console() -> Console:
28
 
29
  # ── Banner ─────────────────────────────────────────────────────────────
30
 
31
- def print_banner() -> None:
32
- Y = "\033[38;2;255;200;50m" # HF yellow
33
- D = "\033[38;2;180;140;40m" # dimmer gold for accents
34
- R = "\033[0m"
35
- art = f"""
36
- {_I}{Y} _ _ _ ___ _ _ {R}
37
- {_I}{Y}| || |_ _ __ _ __ _(_)_ _ __ _ | __|_ _ __ ___ /_\\ __ _ ___ _ _| |_ {R}
38
- {_I}{Y}| __ | || / _` / _` | | ' \\/ _` | | _/ _` / _/ -_) / _ \\/ _` / -_) ' \\ _|{R}
39
- {_I}{Y}|_||_|\\_,_\\__, \\__, |_|_||_\\__, | |_|\\__,_\\__\\___| /_/ \\_\\__, \\___|_||_\\__|{R}
40
- {_I}{D} |___/|___/ |___/ |___/ {R}
41
- """
42
- _console.print(art, highlight=False)
43
- _console.print(f"{_I}[dim]🤗 /help for commands · /quit to exit[/dim]\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
 
46
  # ── Init progress ──────────────────────────────────────────────────────
47
 
48
- def print_init_done() -> None:
49
- _console.print(f"{_I}[dim]Ready.[/dim]\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
 
52
  # ── Tool calls ─────────────────────────────────────────────────────────
53
 
54
  def print_tool_call(tool_name: str, args_preview: str) -> None:
55
- _console.print(f"{_I}[tool.name]▸ {tool_name}[/tool.name] [tool.args]{args_preview}[/tool.args]")
 
 
 
 
 
 
 
 
 
 
 
56
 
57
 
58
  def print_tool_output(output: str, success: bool, truncate: bool = True) -> None:
@@ -146,7 +190,7 @@ class SubAgentDisplay:
146
  lines = []
147
  # Header: ▸ research (stats)
148
  stats = self._format_stats()
149
- header = f"{_I}\033[1;36m▸ research\033[0m"
150
  if stats:
151
  header += f" \033[2m({stats})\033[0m"
152
  lines.append(header)
@@ -183,9 +227,37 @@ def print_tool_log(tool: str, log: str) -> None:
183
  # ── Messages ───────────────────────────────────────────────────────────
184
 
185
  def print_markdown(text: str) -> None:
 
186
  from rich.padding import Padding
 
187
  _console.print()
188
- _console.print(Padding(Markdown(text), (0, 0, 0, 2)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
 
191
  def print_error(message: str) -> None:
 
8
  from rich.theme import Theme
9
 
10
  _THEME = Theme({
11
+ "tool.name": "bold rgb(255,200,80)",
12
  "tool.args": "dim",
13
  "tool.ok": "dim green",
14
  "tool.fail": "dim red",
 
28
 
29
  # ── Banner ─────────────────────────────────────────────────────────────
30
 
31
+ def print_banner(model: str | None = None, hf_user: str | None = None) -> None:
32
+ """Print particle logo then CRT boot sequence with system info."""
33
+ from agent.utils.particle_logo import run_particle_logo
34
+ from agent.utils.crt_boot import run_boot_sequence
35
+
36
+ # Particle coalesce logo — 1.5s converge, 2s hold
37
+ run_particle_logo(_console, hold_seconds=2.0)
38
+
39
+ # Clear screen for CRT boot starts from top
40
+ _console.file.write("\033[2J\033[H")
41
+ _console.file.flush()
42
+
43
+ model_label = model or "anthropic/claude-opus-4-6"
44
+ user_label = hf_user or "not logged in"
45
+
46
+ # Warm gold palette matching the shimmer highlight (255, 200, 80)
47
+ gold = "rgb(255,200,80)"
48
+ dim_gold = "rgb(180,140,40)"
49
+
50
+ boot_lines = [
51
+ (f"{_I}Initializing agent runtime...", gold),
52
+ (f"{_I} User: {user_label}", dim_gold),
53
+ (f"{_I} Model: {model_label}", dim_gold),
54
+ (f"{_I} Tools: loading...", dim_gold),
55
+ ("", ""),
56
+ (f"{_I}/help for commands · /model to switch · /quit to exit", gold),
57
+ ]
58
+
59
+ run_boot_sequence(_console, boot_lines)
60
 
61
 
62
  # ── Init progress ──────────────────────────────────────────────────────
63
 
64
+ def print_init_done(tool_count: int = 0) -> None:
65
+ import time
66
+ f = _console.file
67
+ # Overwrite the "Tools: loading..." line with actual count
68
+ f.write(f"\033[A\033[A\033[A\033[K") # Move up 3 lines (blank + help + blank) then up to tools line
69
+ f.write(f"\033[A\033[K")
70
+ gold = "\033[38;2;180;140;40m"
71
+ reset = "\033[0m"
72
+ tool_text = f"{_I} Tools: {tool_count} loaded"
73
+ for ch in tool_text:
74
+ f.write(f"{gold}{ch}{reset}")
75
+ f.flush()
76
+ time.sleep(0.012)
77
+ f.write("\n\n")
78
+ # Reprint the help line
79
+ f.write(f"{_I}\033[38;2;255;200;80m/help for commands · /model to switch · /quit to exit{reset}\n\n")
80
+ # Ready message — minimal padding
81
+ f.write(f"{_I}\033[38;2;255;200;80mReady. Let's build something impressive.{reset}\n")
82
+ f.flush()
83
 
84
 
85
  # ── Tool calls ─────────────────────────────────────────────────────────
86
 
87
  def print_tool_call(tool_name: str, args_preview: str) -> None:
88
+ import time
89
+ f = _console.file
90
+ # CRT-style: type out tool name in HF yellow
91
+ gold = "\033[38;2;255;200;80m"
92
+ reset = "\033[0m"
93
+ f.write(f"{_I}{gold}▸ ")
94
+ for ch in tool_name:
95
+ f.write(ch)
96
+ f.flush()
97
+ time.sleep(0.015)
98
+ f.write(f"{reset} \033[2m{args_preview}{reset}\n")
99
+ f.flush()
100
 
101
 
102
  def print_tool_output(output: str, success: bool, truncate: bool = True) -> None:
 
190
  lines = []
191
  # Header: ▸ research (stats)
192
  stats = self._format_stats()
193
+ header = f"{_I}\033[38;2;255;200;80m▸ research\033[0m"
194
  if stats:
195
  header += f" \033[2m({stats})\033[0m"
196
  lines.append(header)
 
227
  # ── Messages ───────────────────────────────────────────────────────────
228
 
229
  def print_markdown(text: str) -> None:
230
+ import io, time, random
231
  from rich.padding import Padding
232
+
233
  _console.print()
234
+
235
+ # Render markdown to a string buffer so we can type it out
236
+ buf = io.StringIO()
237
+ buf_console = Console(file=buf, width=_console.width, highlight=False, theme=_THEME)
238
+ buf_console.print(Padding(Markdown(text), (0, 0, 0, 2)))
239
+ rendered = buf.getvalue()
240
+
241
+ # Strip trailing whitespace from each line so we don't type across the full width
242
+ lines = rendered.split("\n")
243
+ rendered = "\n".join(line.rstrip() for line in lines)
244
+
245
+ # CRT typewriter effect — fast, with occasional glitch
246
+ rng = random.Random(42)
247
+ f = _console.file
248
+ for ch in rendered:
249
+ f.write(ch)
250
+ f.flush()
251
+ if ch == "\n":
252
+ time.sleep(0.002)
253
+ elif ch == " ":
254
+ time.sleep(0.002)
255
+ elif rng.random() < 0.03:
256
+ time.sleep(0.015)
257
+ else:
258
+ time.sleep(0.004)
259
+ f.write("\n")
260
+ f.flush()
261
 
262
 
263
  def print_error(message: str) -> None:
pyproject.toml CHANGED
@@ -5,15 +5,11 @@ description = "Add your description here"
5
  readme = "README.md"
6
  requires-python = ">=3.11"
7
  dependencies = [
 
8
  "datasets>=4.4.1",
9
- # Core dependencies (always required)
10
  "pydantic>=2.12.3",
11
  "python-dotenv>=1.2.1",
12
- ]
13
-
14
- [project.optional-dependencies]
15
- # Agent runtime dependencies
16
- agent = [
17
  "requests>=2.33.0",
18
  "litellm>=1.83.0",
19
  "huggingface-hub>=1.0.1",
@@ -23,7 +19,6 @@ agent = [
23
  "rich>=13.0.0",
24
  "nbconvert>=7.16.6",
25
  "nbformat>=5.10.4",
26
- "datasets>=4.3.0", # For session logging to HF datasets
27
  "whoosh>=2.7.4",
28
  # Web backend dependencies
29
  "fastapi>=0.115.0",
@@ -32,6 +27,8 @@ agent = [
32
  "websockets>=13.0",
33
  ]
34
 
 
 
35
  # Evaluation/benchmarking dependencies
36
  eval = [
37
  "inspect-ai>=0.3.149",
@@ -45,9 +42,9 @@ dev = [
45
  "pytest>=9.0.2",
46
  ]
47
 
48
- # All dependencies (agent + eval + dev)
49
  all = [
50
- "hf-agent[agent,eval,dev]",
51
  ]
52
 
53
  [build-system]
 
5
  readme = "README.md"
6
  requires-python = ">=3.11"
7
  dependencies = [
8
+ # Core dependencies
9
  "datasets>=4.4.1",
 
10
  "pydantic>=2.12.3",
11
  "python-dotenv>=1.2.1",
12
+ # Agent runtime dependencies
 
 
 
 
13
  "requests>=2.33.0",
14
  "litellm>=1.83.0",
15
  "huggingface-hub>=1.0.1",
 
19
  "rich>=13.0.0",
20
  "nbconvert>=7.16.6",
21
  "nbformat>=5.10.4",
 
22
  "whoosh>=2.7.4",
23
  # Web backend dependencies
24
  "fastapi>=0.115.0",
 
27
  "websockets>=13.0",
28
  ]
29
 
30
+ [project.optional-dependencies]
31
+
32
  # Evaluation/benchmarking dependencies
33
  eval = [
34
  "inspect-ai>=0.3.149",
 
42
  "pytest>=9.0.2",
43
  ]
44
 
45
+ # All dependencies (eval + dev)
46
  all = [
47
+ "hf-agent[eval,dev]",
48
  ]
49
 
50
  [build-system]
uv.lock CHANGED
@@ -997,13 +997,6 @@ name = "hf-agent"
997
  version = "0.1.0"
998
  source = { editable = "." }
999
  dependencies = [
1000
- { name = "datasets" },
1001
- { name = "pydantic" },
1002
- { name = "python-dotenv" },
1003
- ]
1004
-
1005
- [package.optional-dependencies]
1006
- agent = [
1007
  { name = "datasets" },
1008
  { name = "fastapi" },
1009
  { name = "fastmcp" },
@@ -1013,6 +1006,8 @@ agent = [
1013
  { name = "nbconvert" },
1014
  { name = "nbformat" },
1015
  { name = "prompt-toolkit" },
 
 
1016
  { name = "requests" },
1017
  { name = "rich" },
1018
  { name = "thefuzz" },
@@ -1020,26 +1015,14 @@ agent = [
1020
  { name = "websockets" },
1021
  { name = "whoosh" },
1022
  ]
 
 
1023
  all = [
1024
  { name = "datasets" },
1025
- { name = "fastapi" },
1026
- { name = "fastmcp" },
1027
- { name = "httpx" },
1028
- { name = "huggingface-hub" },
1029
  { name = "inspect-ai" },
1030
- { name = "litellm" },
1031
- { name = "nbconvert" },
1032
- { name = "nbformat" },
1033
  { name = "pandas" },
1034
- { name = "prompt-toolkit" },
1035
  { name = "pytest" },
1036
- { name = "requests" },
1037
- { name = "rich" },
1038
  { name = "tenacity" },
1039
- { name = "thefuzz" },
1040
- { name = "uvicorn", extra = ["standard"] },
1041
- { name = "websockets" },
1042
- { name = "whoosh" },
1043
  ]
1044
  dev = [
1045
  { name = "pytest" },
@@ -1054,31 +1037,30 @@ eval = [
1054
  [package.metadata]
1055
  requires-dist = [
1056
  { name = "datasets", specifier = ">=4.4.1" },
1057
- { name = "datasets", marker = "extra == 'agent'", specifier = ">=4.3.0" },
1058
  { name = "datasets", marker = "extra == 'eval'", specifier = ">=4.3.0" },
1059
- { name = "fastapi", marker = "extra == 'agent'", specifier = ">=0.115.0" },
1060
- { name = "fastmcp", marker = "extra == 'agent'", specifier = ">=3.2.0" },
1061
- { name = "hf-agent", extras = ["agent", "eval", "dev"], marker = "extra == 'all'" },
1062
- { name = "httpx", marker = "extra == 'agent'", specifier = ">=0.27.0" },
1063
- { name = "huggingface-hub", marker = "extra == 'agent'", specifier = ">=1.0.1" },
1064
  { name = "inspect-ai", marker = "extra == 'eval'", specifier = ">=0.3.149" },
1065
- { name = "litellm", marker = "extra == 'agent'", specifier = ">=1.83.0" },
1066
- { name = "nbconvert", marker = "extra == 'agent'", specifier = ">=7.16.6" },
1067
- { name = "nbformat", marker = "extra == 'agent'", specifier = ">=5.10.4" },
1068
  { name = "pandas", marker = "extra == 'eval'", specifier = ">=2.3.3" },
1069
- { name = "prompt-toolkit", marker = "extra == 'agent'", specifier = ">=3.0.0" },
1070
  { name = "pydantic", specifier = ">=2.12.3" },
1071
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" },
1072
  { name = "python-dotenv", specifier = ">=1.2.1" },
1073
- { name = "requests", marker = "extra == 'agent'", specifier = ">=2.33.0" },
1074
- { name = "rich", marker = "extra == 'agent'", specifier = ">=13.0.0" },
1075
  { name = "tenacity", marker = "extra == 'eval'", specifier = ">=8.0.0" },
1076
- { name = "thefuzz", marker = "extra == 'agent'", specifier = ">=0.22.1" },
1077
- { name = "uvicorn", extras = ["standard"], marker = "extra == 'agent'", specifier = ">=0.32.0" },
1078
- { name = "websockets", marker = "extra == 'agent'", specifier = ">=13.0" },
1079
- { name = "whoosh", marker = "extra == 'agent'", specifier = ">=2.7.4" },
1080
  ]
1081
- provides-extras = ["agent", "eval", "dev", "all"]
1082
 
1083
  [[package]]
1084
  name = "hf-xet"
 
997
  version = "0.1.0"
998
  source = { editable = "." }
999
  dependencies = [
 
 
 
 
 
 
 
1000
  { name = "datasets" },
1001
  { name = "fastapi" },
1002
  { name = "fastmcp" },
 
1006
  { name = "nbconvert" },
1007
  { name = "nbformat" },
1008
  { name = "prompt-toolkit" },
1009
+ { name = "pydantic" },
1010
+ { name = "python-dotenv" },
1011
  { name = "requests" },
1012
  { name = "rich" },
1013
  { name = "thefuzz" },
 
1015
  { name = "websockets" },
1016
  { name = "whoosh" },
1017
  ]
1018
+
1019
+ [package.optional-dependencies]
1020
  all = [
1021
  { name = "datasets" },
 
 
 
 
1022
  { name = "inspect-ai" },
 
 
 
1023
  { name = "pandas" },
 
1024
  { name = "pytest" },
 
 
1025
  { name = "tenacity" },
 
 
 
 
1026
  ]
1027
  dev = [
1028
  { name = "pytest" },
 
1037
  [package.metadata]
1038
  requires-dist = [
1039
  { name = "datasets", specifier = ">=4.4.1" },
 
1040
  { name = "datasets", marker = "extra == 'eval'", specifier = ">=4.3.0" },
1041
+ { name = "fastapi", specifier = ">=0.115.0" },
1042
+ { name = "fastmcp", specifier = ">=3.2.0" },
1043
+ { name = "hf-agent", extras = ["eval", "dev"], marker = "extra == 'all'" },
1044
+ { name = "httpx", specifier = ">=0.27.0" },
1045
+ { name = "huggingface-hub", specifier = ">=1.0.1" },
1046
  { name = "inspect-ai", marker = "extra == 'eval'", specifier = ">=0.3.149" },
1047
+ { name = "litellm", specifier = ">=1.83.0" },
1048
+ { name = "nbconvert", specifier = ">=7.16.6" },
1049
+ { name = "nbformat", specifier = ">=5.10.4" },
1050
  { name = "pandas", marker = "extra == 'eval'", specifier = ">=2.3.3" },
1051
+ { name = "prompt-toolkit", specifier = ">=3.0.0" },
1052
  { name = "pydantic", specifier = ">=2.12.3" },
1053
  { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" },
1054
  { name = "python-dotenv", specifier = ">=1.2.1" },
1055
+ { name = "requests", specifier = ">=2.33.0" },
1056
+ { name = "rich", specifier = ">=13.0.0" },
1057
  { name = "tenacity", marker = "extra == 'eval'", specifier = ">=8.0.0" },
1058
+ { name = "thefuzz", specifier = ">=0.22.1" },
1059
+ { name = "uvicorn", extras = ["standard"], specifier = ">=0.32.0" },
1060
+ { name = "websockets", specifier = ">=13.0" },
1061
+ { name = "whoosh", specifier = ">=2.7.4" },
1062
  ]
1063
+ provides-extras = ["eval", "dev", "all"]
1064
 
1065
  [[package]]
1066
  name = "hf-xet"