gemcode 0.3.46__py3-none-any.whl → 0.3.48__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.
gemcode/agent.py CHANGED
@@ -398,27 +398,19 @@ You run locally via the GemCode CLI. You are the same agent the user launched
398
398
 
399
399
  ## Core identity and approach
400
400
 
401
- ### Intent-aware workflow
401
+ Use your built-in thinking to read the user's intent before acting. Match the response style to what was actually asked:
402
402
 
403
- Before you see this message, a **gemini-2.5-flash-lite** intent classifier already determined the user's intent
404
- and stored it in session state as `_gemcode_intent`. Read it and adapt your behaviour:
405
-
406
- | `_gemcode_intent` | Meaning | What to do |
403
+ | Message type | Examples | Right action |
407
404
  |---|---|---|
408
- | `GREETING` | Social / chitchat | *(You will never see this handled upstream before reaching you.)* |
409
- | `CONCEPT` | General knowledge question | Answer from your training knowledge. No tools unless the answer truly requires this repo's files. |
410
- | `PROJECT_QUESTION` | Question about this codebase | Use 1–2 focused read-only tools (`list_directory`, `read_file`, `grep_content`) to find the answer, then reply concisely. |
411
- | `ENGINEERING_TASK` | Code modification / fix / build | Full workflow: **Orient → Plan → Execute → Verify**. |
412
- | `ANALYSIS` | Systematic audit or summarisation | Thorough tool sweep: list read grep across the affected area, then synthesise findings. |
413
-
414
- If `_gemcode_intent` is not set (first turn or classifier unavailable), infer the intent yourself
415
- from the message before acting — the categories above still apply.
405
+ | **Greeting / chitchat** | "hi", "thanks", "cool" | Reply warmly in one sentence. No tools. |
406
+ | **General knowledge** | "what is a closure?", "explain OAuth" | Answer from knowledge. No tools unless this specific repo is needed. |
407
+ | **Project question** | "how does auth work here?", "what's in this folder?" | 1–2 read-only tools, then a focused answer. |
408
+ | **Engineering task** | "fix the bug", "add pagination", "refactor X" | Orient → Plan → Execute → Verify. |
409
+ | **Analysis / audit** | "analyse the whole backend", "summarise all endpoints" | Thorough tool sweep, then synthesise. |
416
410
 
417
- **Under no circumstances call `list_directory`, `read_project_notes`, or any tool in
418
- response to a greeting or a simple general question that requires no project context.**
411
+ **Never call `list_directory`, `read_project_notes`, or any tool in response to a greeting or a general knowledge question that needs no project context.**
419
412
 
420
413
  ### Engineering task workflow
421
- When the intent is `ENGINEERING_TASK`:
422
414
  1. **Orient** — use `list_directory`, `glob_files`, `grep_content`, `read_file` to understand structure. These tools need **no permission** and are instant.
423
415
  2. **Plan** — for complex tasks, call `todo_write` upfront to map out the work.
424
416
  3. **Execute** — make the changes, run the checks, iterate.
@@ -447,7 +439,7 @@ You have native deep thinking capability — use it actively:
447
439
  - **For trade-off decisions** (which library, which pattern, which approach): reason through the pros/cons given this specific codebase.
448
440
 
449
441
  ## Interpreting requests
450
- - **Let `_gemcode_intent` guide you.** The pre-classifier already did the hard work. Trust it and act accordingly (see the table above).
442
+ - **Think first.** Read the message intent before touching any tool. The intent table above is your guide.
451
443
  - **Engineering tasks** ("fix", "add", "refactor", "analyse", "debug"): infer from the repo — search, read, then act. Do not give abstract advice when concrete files exist.
452
444
  - If the user refers to symbols or behaviors, **find them** with `glob_files`/`grep_content`/`list_directory` — never ask them to paste paths you can discover yourself.
453
445
  - **Never propose edits to files you haven't read.** Read first, then edit.
@@ -470,12 +462,12 @@ You have native deep thinking capability — use it actively:
470
462
  - For **dev servers**: `bash("npm run dev", background=True, cwd_subdir="frontend")`
471
463
  - For **subfolders**: `bash("cargo build --release", cwd_subdir="backend")`
472
464
 
473
- - **`bash_stream`** — streaming version of bash: yields stdout line-by-line in real-time. Use for long-running commands where the user wants to see live progress:
474
- - `bash_stream("pytest -v tests/")` — see each test result as it runs
475
- - `bash_stream("npm run build")` — watch build progress in real-time
476
- - `bash_stream("pip install -r requirements.txt")` — see install progress
477
- - `bash_stream("tail -f logs/app.log", timeout_seconds=60)` — live log watching
478
- - Prefer `bash_stream` over `bash` whenever the command takes > 5 seconds and progress visibility matters
465
+ - **Long-running servers / watchers** use `bash` with `background=True`:
466
+ - `bash("npm run dev", background=True)` — start the dev server in background
467
+ - `bash("python manage.py runserver", background=True)` — Django server
468
+ - `bash("tail -f logs/app.log", background=True)` — background log watcher
469
+ - NEVER call `bash("npm run dev")` without `background=True` — it blocks forever and crashes the turn
470
+ - After starting a background process, confirm the port is ready with `bash("sleep 2 && curl -s http://localhost:3000 -o /dev/null && echo ready")`
479
471
 
480
472
  - **`run_command`** — simple single-executable calls without shell features:
481
473
  - `run_command("npm", args=["install", "--legacy-peer-deps"])` — clean npm install
@@ -769,8 +761,10 @@ def build_root_agent(
769
761
  # prepended to every agent's effective instruction.
770
762
  global_instr = (
771
763
  "You are GemCode, an expert software engineering agent powered by Google Gemini. "
772
- "Act, don't advise. Complete tasks fully and autonomously. "
773
- "Think before destructive actions. Use read-only tools before shell/write tools."
764
+ "Think through the user's intent before acting. "
765
+ "For greetings or general questions, reply directly without calling tools. "
766
+ "For engineering tasks, act fully and autonomously — orient, plan, execute, verify. "
767
+ "Use read-only tools before shell/write tools."
774
768
  )
775
769
 
776
770
  agent_kwargs: dict = dict(
gemcode/cli.py CHANGED
@@ -154,17 +154,6 @@ async def _run_prompt(
154
154
  # MCP and OpenAPI toolsets are now loaded inside create_runner() directly.
155
155
  runner = create_runner(cfg, extra_tools=None)
156
156
  try:
157
- # LLM intent pre-classifier: greetings bypass the main agent entirely.
158
- try:
159
- from gemcode.intent_classifier import (
160
- classify_intent, generate_greeting_reply, INTENT_GREETING
161
- )
162
- _intent = await classify_intent(prompt)
163
- if _intent == INTENT_GREETING:
164
- return await generate_greeting_reply(prompt)
165
- except Exception:
166
- pass
167
-
168
157
  collected = await run_turn(
169
158
  runner,
170
159
  user_id="local",
gemcode/config.py CHANGED
@@ -68,7 +68,7 @@ class GemCodeConfig:
68
68
  """Runtime options (CLI + env)."""
69
69
 
70
70
  project_root: Path
71
- model: str = field(default_factory=lambda: os.environ.get("GEMCODE_MODEL", "gemini-2.5-flash"))
71
+ model: str = field(default_factory=lambda: os.environ.get("GEMCODE_MODEL", "gemini-3.1-pro-preview"))
72
72
  # Model mode: fast|balanced|quality|auto
73
73
  model_mode: str = field(
74
74
  default_factory=lambda: os.environ.get("GEMCODE_MODEL_MODE", "fast")
gemcode/pricing.py CHANGED
@@ -14,6 +14,10 @@ from __future__ import annotations
14
14
  # Format: model_prefix → (input_$/M, output_$/M)
15
15
  # Matches are done by checking if the model id STARTS WITH any key (longest first).
16
16
  _PRICING_TABLE: dict[str, tuple[float, float]] = {
17
+ # ── Gemini 3 ────────────────────────────────────────────────────────────
18
+ "gemini-3.1-pro": (0.30, 1.20), # preview pricing (approximate)
19
+ "gemini-3.0-pro": (0.30, 1.20),
20
+ "gemini-3": (0.30, 1.20),
17
21
  # ── Gemini 2.5 ──────────────────────────────────────────────────────────
18
22
  "gemini-2.5-pro": (3.50, 10.50), # standard context ≤200k
19
23
  "gemini-2.5-flash-lite": (0.10, 0.40), # lowest-cost 2.5 (must precede flash)
@@ -28,7 +32,6 @@ _PRICING_TABLE: dict[str, tuple[float, float]] = {
28
32
  "gemini-1.5-pro": (1.25, 5.00),
29
33
  # ── Gemini experimental / preview ───────────────────────────────────────
30
34
  "gemini-exp": (0.00, 0.00), # free during preview
31
- "gemini-3": (0.30, 1.20), # approximate future pricing
32
35
  }
33
36
 
34
37
 
gemcode/tools/__init__.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from gemcode.config import GemCodeConfig
6
- from gemcode.tools.bash import make_bash_tool, make_bash_stream_tool
6
+ from gemcode.tools.bash import make_bash_tool
7
7
  from gemcode.tools.edit import make_edit_tools
8
8
  from gemcode.tools.filesystem import make_filesystem_tools
9
9
  from gemcode.tools.search import make_grep_tool
@@ -35,7 +35,6 @@ def build_function_tools(cfg: GemCodeConfig, *, include_subtask: bool = True) ->
35
35
  grep_content = make_grep_tool(cfg)
36
36
  run_command = make_run_command(cfg)
37
37
  bash = make_bash_tool(cfg)
38
- bash_stream = make_bash_stream_tool(cfg)
39
38
  write_file, search_replace = make_edit_tools(cfg)
40
39
  todo_write = make_todo_tool(cfg)
41
40
  think = make_think_tool()
@@ -55,7 +54,6 @@ def build_function_tools(cfg: GemCodeConfig, *, include_subtask: bool = True) ->
55
54
  glob_files,
56
55
  grep_content,
57
56
  bash_tool,
58
- bash_stream,
59
57
  run_command_tool,
60
58
  write_file,
61
59
  search_replace,
gemcode/tui/scrollback.py CHANGED
@@ -582,61 +582,6 @@ async def run_gemcode_scrollback_tui(
582
582
  except Exception:
583
583
  pass
584
584
 
585
- # ── LLM intent pre-classifier ────────────────────────────────────────────
586
- # gemini-2.5-flash-lite classifies the message (same lane as Thinking)
587
- try:
588
- from gemcode.intent_classifier import (
589
- classify_intent_with_source,
590
- generate_greeting_reply,
591
- show_intentifying_line,
592
- INTENT_GREETING,
593
- INTENT_DESCRIPTIONS,
594
- )
595
- # Show as a transient spinner status (do not print a permanent line).
596
- _start_anim("Intentifying\u2026")
597
- try:
598
- _intent, _intent_src = await classify_intent_with_source(prompt)
599
- finally:
600
- _stop_anim()
601
- # If disabled, show nothing; otherwise the spinner already conveyed it.
602
- _ = show_intentifying_line(_intent_src)
603
-
604
- if _intent == INTENT_GREETING:
605
- _start_anim("Replying\u2026")
606
- try:
607
- _reply = await generate_greeting_reply(prompt)
608
- finally:
609
- _stop_anim()
610
- print(f" \u23bf {ansi.bold}GemCode{ansi.reset}:")
611
- console.print(_RichPadding(_RichMarkdown(_reply), (0, 0, 0, 4)))
612
- print("")
613
- if os.environ.get("GEMCODE_TUI_TURN_RULE", "1").lower() in (
614
- "1", "true", "yes", "on"
615
- ):
616
- print(f"{ansi.dim}{_hr(ch='─')}{ansi.reset}")
617
- print("")
618
- continue
619
-
620
- # Non-greeting: store classified intent in session state so the main
621
- # agent can read it and adapt its tool-use strategy accordingly.
622
- try:
623
- ss = runner.session_service
624
- app = getattr(runner, "app_name", None) or getattr(cfg, "app_name", "gemcode")
625
- sess = await ss.get_session(
626
- app_name=app, user_id="local", session_id=current_session_id
627
- )
628
- if sess is not None:
629
- _desc = INTENT_DESCRIPTIONS.get(_intent, _intent)
630
- sess.state["_gemcode_intent"] = _intent
631
- sess.state["_gemcode_intent_desc"] = _desc
632
- await ss.update_session(sess)
633
- except Exception:
634
- pass # State injection is best-effort
635
-
636
- except Exception:
637
- pass # Classifier unavailable — fall through to main agent unchanged
638
- # ─────────────────────────────────────────────────────────────────────────
639
-
640
585
  # Snapshot pre-turn capability state so we can detect routing-triggered changes.
641
586
  _pre_dr = cfg.enable_deep_research
642
587
  _pre_emb = cfg.enable_embeddings
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.46
3
+ Version: 0.3.48
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -1,13 +1,13 @@
1
1
  gemcode/__init__.py,sha256=l0DCRYqK7KM7Fb7u49fqh-5_SlpeIL7r3LjMeJWMgSg,112
2
2
  gemcode/__main__.py,sha256=EX2s1hxq2Yvli_-tnBN3w5Qv4bOjsBBbjyISF0pDIQw,37
3
- gemcode/agent.py,sha256=ODiOL6e2vDuXEHdiEmn71xKx7Lk4O-_uePmaavROVgA,42229
3
+ gemcode/agent.py,sha256=2PVjjSiI4siJFrqkP6Ca6v7ecHrJywZOHs3PG_wSwgk,41884
4
4
  gemcode/audit.py,sha256=bh9uhXaeh8wqxqoZtz3ZAowd8Ndk1ss-mw9993Vlrgo,469
5
5
  gemcode/autocompact.py,sha256=77h5tgFzJ2rjrhlCL2oIc28IHwLbP4Pqlo7cSNgDwiA,6727
6
6
  gemcode/callbacks.py,sha256=qgbxyBMOlgzVkJr9lI55En4EpJOwjo83U3dvNrl5I4s,24229
7
7
  gemcode/capability_routing.py,sha256=D8tvawmf_MSL94GVXgG9QhDvNaQVGqzA8tUFQ8XlftY,2894
8
- gemcode/cli.py,sha256=J0mT5yHEw1pLm0U3aFRrGw5PAb2uGapxHfxadX-4dnE,25696
8
+ gemcode/cli.py,sha256=kBXb4b4JCG3u0XewCJn8lCyOT62Y8bOvlVoDc2R-GKQ,25320
9
9
  gemcode/compaction.py,sha256=9YtA_qa23_8dHWVHx7AJwUduuI7jJQtq-m6sT8jgPWI,1186
10
- gemcode/config.py,sha256=GKbze1nDf1U5O-i6AmKd9FYr92TklJ2Vhi3qdKrhqZw,14081
10
+ gemcode/config.py,sha256=Ngwbp96FzplhA_F5XPW_VvCmAekConR2OG6GBGDjJew,14087
11
11
  gemcode/context_budget.py,sha256=Nhox9vFBtLbb7jtO7cyGW1MxtN7SVjlIeQ7d-cgGyKM,10544
12
12
  gemcode/context_warning.py,sha256=Q8mg5Vojj7EglPhsGAVL7vb8ROLuHVPgdzw25yw-Q2c,4263
13
13
  gemcode/credentials.py,sha256=04v-rLD8_Ams69FQdof2FwcL3ZgsroGUnMcHNQFuBZo,1296
@@ -27,7 +27,7 @@ gemcode/model_routing.py,sha256=Q42HZtXQa6rao2O2vYMHxohrTgD-wq4t7qGxU4_38Jg,4881
27
27
  gemcode/openapi_loader.py,sha256=g_NZD8YL9_9iIJJ9qykhdbBrylJ1195A4FyHGC0mroc,4157
28
28
  gemcode/paths.py,sha256=U6cEH9jfIcSc4NO8Ke0jniZSiJTfCIJPvSMue3hR0ZU,768
29
29
  gemcode/permissions.py,sha256=0gQ63Ll-KPlZVU6KigIpwSwKL5-OWqYMB6a0x2wpc28,6766
30
- gemcode/pricing.py,sha256=G8rH_JuB-7JeHpTbwJJz1TIvN22vuHUsWSbDjYwTjr8,3262
30
+ gemcode/pricing.py,sha256=lftp0SwyDqOzHqC2-6XzgZZhjif5PLdCe1Q3wY-p6kQ,3558
31
31
  gemcode/prompt_suggestions.py,sha256=h-W_9LlfagS91PyoMEjEjsCqoG4XmIh3QBypA59HyGw,2553
32
32
  gemcode/refine.py,sha256=BijEZ4Z32wGa9aK_WottyAhZF-j0xEqRg5UpjedNv2A,7653
33
33
  gemcode/repl_commands.py,sha256=qPUVSjNLR0QnABmURoYP58quu2pAcz3F0wUvDd_1v3o,11340
@@ -59,7 +59,7 @@ gemcode/query/engine.py,sha256=GPuvUgTRpWmyA39I_3ayVEADlHVFhPrC2FGW_yKs2yw,1420
59
59
  gemcode/query/stop_hooks.py,sha256=jaXMN2OptwHeGXF8o630zIVr62T8jVg-eIyREG0GyxA,1847
60
60
  gemcode/query/token_budget.py,sha256=JTq2TrGkFY5t5KOs-P9XQPqahyjcdTzN3wctZ1JxFV0,2973
61
61
  gemcode/query/transitions.py,sha256=vJ77cv4cFwdvsxyGr7MxXz6uGVB5IDqOClqR1MkWvqw,933
62
- gemcode/tools/__init__.py,sha256=dfZIgOO3ySpVf6hIvZkiN7asZNHW5FMQjMDGAQtFqho,2309
62
+ gemcode/tools/__init__.py,sha256=jea95Ds3BwUaiDNVGesBXDKvveIHbdTNpk4yKVWcPVA,2226
63
63
  gemcode/tools/bash.py,sha256=1Nv1UmnWhc1Y-9gZyYUQEcAE43K8V2bakj27ULcvjR8,9075
64
64
  gemcode/tools/browser.py,sha256=StWRttiyGkR4qaG5urRviJgdoj2hiFB2OuHPItaVzJY,7250
65
65
  gemcode/tools/edit.py,sha256=Q6ALUCHQV37n0j6XQd2luCaDm0fIavho3faDisOqtuU,1716
@@ -73,16 +73,16 @@ gemcode/tools/think.py,sha256=WrNATR-bi97aLkbSsOFOYYAGxbzihe9AnPDZfw3z5-Q,1704
73
73
  gemcode/tools/todo.py,sha256=d9aXiyT04r1RFZIk6qdVif17-_Oc3oi4ymDnsPBRg68,3143
74
74
  gemcode/tools/web.py,sha256=ULg1e3inG4FjPSUCYI8dVBzTrcCHINNRo76SIU9qw-A,4489
75
75
  gemcode/tui/input_handler.py,sha256=VWF92Fe3WkD3QP9kBDY5zrx333Vj2eShO3UO0x2n6eo,10079
76
- gemcode/tui/scrollback.py,sha256=7b7knFb6iRmwwiPKFkKApW0Dqah5QtNbFMMvAorBE58,34950
76
+ gemcode/tui/scrollback.py,sha256=RxwS0DsjkkX_jHvnlF2XMi9z69yGfCiwPuFIHCnb8VU,32535
77
77
  gemcode/tui/spinner.py,sha256=AJrApG5od-Sh40-5uWcNM9RHb5ax7gr-NbgAZmTbIYY,4848
78
78
  gemcode/tui/welcome_banner.py,sha256=aocl1lnoyLIM6RN4f65g3i0wRA71RqUlgPrGsXeVLW4,4387
79
79
  gemcode/tui/welcome_rich.py,sha256=8FEZzLXrzqly5JWiDgV9ooRV1LNXDk-CXV1a7K6ua-U,4048
80
80
  gemcode/web/__init__.py,sha256=EysmUAWs6g-lmMk4VFljKfaHVrEgb_FiIzwQmBdORJc,40
81
81
  gemcode/web/claude_sse_adapter.py,sha256=HcNp0Lh4DdBZBLOpstsqa-VzfqAUrRngZ6FSuJ-mIMg,8609
82
82
  gemcode/web/terminal_repl.py,sha256=k2irvFGbCY8gDm_pbirR7b_cakaeafcctoTIvnJkVXk,3902
83
- gemcode-0.3.46.dist-info/licenses/LICENSE,sha256=TD4524qn-W8Z07GTDnag-9jJPFutFZNB0a1WbMHPC54,8388
84
- gemcode-0.3.46.dist-info/METADATA,sha256=Ezcxs4DisacoIdLLUsOpgjoLG9_hyrgxmetVsKhSosk,23695
85
- gemcode-0.3.46.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
86
- gemcode-0.3.46.dist-info/entry_points.txt,sha256=cZdLTLDiHbks7OSUCuxCh66dCWeQdpLR8BozoqfEjV4,45
87
- gemcode-0.3.46.dist-info/top_level.txt,sha256=UYrjULLBY2bcgK6KI6flomJWmsbDXu7n0rvW2SWFrbo,8
88
- gemcode-0.3.46.dist-info/RECORD,,
83
+ gemcode-0.3.48.dist-info/licenses/LICENSE,sha256=TD4524qn-W8Z07GTDnag-9jJPFutFZNB0a1WbMHPC54,8388
84
+ gemcode-0.3.48.dist-info/METADATA,sha256=gqGKCCsfE6Ppuf1x0ZlJR-qzsi38hWkPJmMB_H2NA8E,23695
85
+ gemcode-0.3.48.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
86
+ gemcode-0.3.48.dist-info/entry_points.txt,sha256=cZdLTLDiHbks7OSUCuxCh66dCWeQdpLR8BozoqfEjV4,45
87
+ gemcode-0.3.48.dist-info/top_level.txt,sha256=UYrjULLBY2bcgK6KI6flomJWmsbDXu7n0rvW2SWFrbo,8
88
+ gemcode-0.3.48.dist-info/RECORD,,