gemcode 0.3.97__py3-none-any.whl → 0.3.98__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/invoke.py CHANGED
@@ -184,15 +184,33 @@ async def run_turn(
184
184
  # user-granted "Files and Folders" permissions on first access.
185
185
  # If approved once, we don't re-prompt for the rest of this session.
186
186
  attach_allow = True
187
- if cfg is not None:
188
- attach_allow = bool(getattr(cfg, "interactive_permission_ask", False))
189
- attach_allow = attach_allow and hasattr(sys.stdin, "isatty") and sys.stdin.isatty()
190
- if attach_allow and not bool(getattr(cfg, "_attachments_allowed", False)):
191
- attach_allow = _prompt_yes_no(
192
- "Allow GemCode to read and upload the attached file(s) from disk? (y/n) "
193
- )
194
- if attach_allow:
187
+ if hasattr(sys.stdin, "isatty") and sys.stdin.isatty():
188
+ # Default-on: attachments can read any local file path (not workspace-scoped),
189
+ # but we ask once per session so the user is in control and macOS can trigger
190
+ # its permission prompt at the moment we attempt the read.
191
+ attach_allow = os.environ.get("GEMCODE_ATTACHMENTS_ASK", "1").lower() not in (
192
+ "0",
193
+ "false",
194
+ "no",
195
+ "off",
196
+ )
197
+ if cfg is not None:
198
+ # If user already approved earlier in this session, don't prompt again.
199
+ if bool(getattr(cfg, "_attachments_allowed", False)):
200
+ attach_allow = True
201
+ # If yes-to-all is enabled, auto-allow attachments.
202
+ elif bool(getattr(cfg, "yes_to_all", False)):
203
+ attach_allow = True
195
204
  object.__setattr__(cfg, "_attachments_allowed", True)
205
+ elif attach_allow:
206
+ attach_allow = _prompt_yes_no(
207
+ "Allow GemCode to read and upload the attached file(s) from disk? (y/n) "
208
+ )
209
+ if attach_allow:
210
+ object.__setattr__(cfg, "_attachments_allowed", True)
211
+ else:
212
+ # Non-interactive sessions can't prompt; default to allow.
213
+ attach_allow = True
196
214
  effective_attachments = attachment_paths if attach_allow else None
197
215
 
198
216
  root = cfg.project_root if cfg is not None else Path.cwd()
@@ -97,6 +97,18 @@ def _infer_mime(path: Path, data: bytes) -> tuple[str, list[str]]:
97
97
  return "application/octet-stream", warnings
98
98
 
99
99
 
100
+ def _is_supported_mime(m: str) -> bool:
101
+ mm = (m or "").strip().lower()
102
+ if not mm:
103
+ return False
104
+ if mm.startswith(("image/", "audio/", "video/", "text/")):
105
+ return True
106
+ if mm == "application/pdf":
107
+ return True
108
+ # Most other application/* types are rejected by Gemini file parts.
109
+ return False
110
+
111
+
100
112
  def build_user_content(
101
113
  prompt: str,
102
114
  attachment_paths: Sequence[Path | str] | None,
@@ -135,6 +147,12 @@ def build_user_content(
135
147
  continue
136
148
  mime, mw = _infer_mime(p, data)
137
149
  warnings.extend(mw)
150
+ if not _is_supported_mime(mime) or mime == "application/octet-stream":
151
+ warnings.append(
152
+ f"unsupported attachment type for {p} (mime={mime}); "
153
+ "skipping (export to PDF/image/text if needed)"
154
+ )
155
+ continue
138
156
  parts.append(types.Part(inline_data=types.Blob(data=data, mime_type=mime)))
139
157
 
140
158
  text = (prompt or "").strip() or (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.97
3
+ Version: 0.3.98
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -21,7 +21,7 @@ gemcode/ide_protocol.py,sha256=WJO4KdwyxjQcH1O_vTn7SPuy1ZZMm0eC8_xRLA9RYQo,2108
21
21
  gemcode/ide_stdio.py,sha256=qDZ8qCR0kWipvyxLJ3tbZfAXChZtosi46dLeNuMejFk,11066
22
22
  gemcode/intent_classifier.py,sha256=YfRVEe8gHeKlRkjuSWef1bZ0MPBwyYMp5jymP5Vig5U,8507
23
23
  gemcode/interactions.py,sha256=B0b3QNE_I2i5_HtiebX4ehhjlc4Nbqjf_XbvcTLyJT0,641
24
- gemcode/invoke.py,sha256=mjCxQGlkZVaIh2eRxsxaojZGrV3FikMqoVCpNo0CV50,11904
24
+ gemcode/invoke.py,sha256=CpDnz3v8NdWPV9JTJVfh2nzkIGN7I7ihIw452QJhEcI,12694
25
25
  gemcode/kaira_daemon.py,sha256=Bzkpc96HocfYAV9D5skid_Gi4bJDOLgO5YlD8vbTgyY,6960
26
26
  gemcode/learning.py,sha256=o4Ivczm626NPRiNbSEb7-RvKJMefnv0ZpYt4UB2C3JA,3856
27
27
  gemcode/limits.py,sha256=3j6N8V643X7-nP-cAIf37Xg9bkGpQlEJB3nPptApQWk,2504
@@ -31,7 +31,7 @@ gemcode/mcp_loader.py,sha256=alipHTl5aA7ZCPG6Rq9cyy3UZLsdCra0CETb_fRJl_k,4964
31
31
  gemcode/modality_tools.py,sha256=L2U756l0YM4SOUx5YxcKEkjSF1QOGzFOSE4o3U0q-4Y,7213
32
32
  gemcode/model_errors.py,sha256=j1nb1dopJyZ6MQQvuuADBqvmcqdL80kQWACuWKMkP4Q,4185
33
33
  gemcode/model_routing.py,sha256=_8mnXNwxMPA8wAfl-Yx5lWNgjhyWYTCCCMGlqdGAw90,5174
34
- gemcode/multimodal_input.py,sha256=FrfwcmqgDKnPDWxj76GOltl34D3PNQHxgbSR7ykL8SU,4450
34
+ gemcode/multimodal_input.py,sha256=eLFNj_yAykvoTMyiv0hGUXMgb6xlN4pyZ6X--swhnw0,5015
35
35
  gemcode/openapi_loader.py,sha256=g_NZD8YL9_9iIJJ9qykhdbBrylJ1195A4FyHGC0mroc,4157
36
36
  gemcode/output_styles.py,sha256=6ZgbEsEM5qbdGDZMuRFRHAmHCoKpi53SqPqXZ2sfbS4,2189
37
37
  gemcode/paths.py,sha256=UQp4R4sUBv7HsM2OVoGlPxyOIOQZE5wpY53G6nHpB5Q,2671
@@ -107,9 +107,9 @@ gemcode/web/__init__.py,sha256=EysmUAWs6g-lmMk4VFljKfaHVrEgb_FiIzwQmBdORJc,40
107
107
  gemcode/web/sse_adapter.py,sha256=fXhKxn_bdJJUGqlmvkxLNSYL-ZiIZDaLHtQCF_BheRc,7108
108
108
  gemcode/web/terminal_repl.py,sha256=fQt895g0qcr6VBhXfv_5b_bsC5zHT5-MO0ysBdgi2Fg,3886
109
109
  gemcode/web/web_sse_compat.py,sha256=9A2s-GI7El7AotJqhO263FrLwppCXXkdydZ5EiOQbao,504
110
- gemcode-0.3.97.dist-info/licenses/LICENSE,sha256=TD4524qn-W8Z07GTDnag-9jJPFutFZNB0a1WbMHPC54,8388
111
- gemcode-0.3.97.dist-info/METADATA,sha256=-rLJq9S6zklxs9L4oMQ3RVatlE4MkOUlcfvtkgTZvwo,17084
112
- gemcode-0.3.97.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
113
- gemcode-0.3.97.dist-info/entry_points.txt,sha256=cZdLTLDiHbks7OSUCuxCh66dCWeQdpLR8BozoqfEjV4,45
114
- gemcode-0.3.97.dist-info/top_level.txt,sha256=UYrjULLBY2bcgK6KI6flomJWmsbDXu7n0rvW2SWFrbo,8
115
- gemcode-0.3.97.dist-info/RECORD,,
110
+ gemcode-0.3.98.dist-info/licenses/LICENSE,sha256=TD4524qn-W8Z07GTDnag-9jJPFutFZNB0a1WbMHPC54,8388
111
+ gemcode-0.3.98.dist-info/METADATA,sha256=2AIF7Xt3GbmT8oNW8tLJRbq6SzkExsyyLat7y5aTQgE,17084
112
+ gemcode-0.3.98.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
113
+ gemcode-0.3.98.dist-info/entry_points.txt,sha256=cZdLTLDiHbks7OSUCuxCh66dCWeQdpLR8BozoqfEjV4,45
114
+ gemcode-0.3.98.dist-info/top_level.txt,sha256=UYrjULLBY2bcgK6KI6flomJWmsbDXu7n0rvW2SWFrbo,8
115
+ gemcode-0.3.98.dist-info/RECORD,,