jac-coder 0.2.8__tar.gz → 0.2.9__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.
Files changed (102) hide show
  1. {jac_coder-0.2.8 → jac_coder-0.2.9}/PKG-INFO +5 -2
  2. {jac_coder-0.2.8 → jac_coder-0.2.9}/README.md +1 -3
  3. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/api.impl.jac +0 -61
  4. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/api.jac +1 -9
  5. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/cli.jac +2 -7
  6. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/core/nodes.impl.jac +0 -62
  7. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/core/nodes.jac +1 -46
  8. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/core/walkers.impl.jac +0 -1
  9. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/core/walkers.jac +1 -9
  10. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/config.jac +0 -1
  11. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/events.jac +15 -3
  12. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/kv.jac +10 -1
  13. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/mcp_manager.jac +0 -1
  14. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/lib/coder.impl.jac +1 -1
  15. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/lib/coder.jac +1 -1
  16. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/context.impl.jac +2 -2
  17. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/cost_tracker.impl.jac +0 -2
  18. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/file_logger.jac +0 -6
  19. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/permission.impl.jac +1 -2
  20. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/prompt.impl.jac +0 -4
  21. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/prompt.jac +0 -2
  22. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/skills.jac +0 -3
  23. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/__init__.jac +0 -1
  24. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/git.impl.jac +0 -2
  25. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/delegation.impl.jac +0 -3
  26. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/delegation.jac +1 -1
  27. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/filesystem.impl.jac +0 -2
  28. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/filesystem.jac +0 -1
  29. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/jac_analyzer.impl.jac +0 -108
  30. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/jac_analyzer.jac +0 -4
  31. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/shell.jac +0 -1
  32. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/write/checked.impl.jac +0 -3
  33. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/tool_output.impl.jac +0 -2
  34. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder.egg-info/PKG-INFO +5 -2
  35. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder.egg-info/SOURCES.txt +0 -6
  36. jac_coder-0.2.9/jac_coder.egg-info/requires.txt +8 -0
  37. {jac_coder-0.2.8 → jac_coder-0.2.9}/pyproject.toml +5 -2
  38. jac_coder-0.2.8/jac_coder/runtime/memory.impl.jac +0 -247
  39. jac_coder-0.2.8/jac_coder/runtime/memory.jac +0 -21
  40. jac_coder-0.2.8/jac_coder/tool/meta/task.impl.jac +0 -12
  41. jac_coder-0.2.8/jac_coder/tool/meta/task.jac +0 -9
  42. jac_coder-0.2.8/jac_coder/tool/meta/validate.impl.jac +0 -254
  43. jac_coder-0.2.8/jac_coder/tool/meta/validate.jac +0 -11
  44. jac_coder-0.2.8/jac_coder.egg-info/requires.txt +0 -5
  45. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/__init__.jac +0 -0
  46. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/__init__.py +0 -0
  47. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/cli.impl.jac +0 -0
  48. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/cli_entry.py +0 -0
  49. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/core/__init__.jac +0 -0
  50. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/__init__.jac +0 -0
  51. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/config.impl.jac +0 -0
  52. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/infra/mcp_manager.impl.jac +0 -0
  53. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/lib/__init__.jac +0 -0
  54. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/__init__.jac +0 -0
  55. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/compaction.jac +0 -0
  56. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/context.jac +0 -0
  57. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/cost_tracker.jac +0 -0
  58. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/events.jac +0 -0
  59. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/permission.jac +0 -0
  60. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/skills.impl.jac +0 -0
  61. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/runtime/struggle_report.jac +0 -0
  62. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/serve_entry.jac +0 -0
  63. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/server.jac +0 -0
  64. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/git.jac +0 -0
  65. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/mcp.impl.jac +0 -0
  66. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/mcp.jac +0 -0
  67. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/__init__.jac +0 -0
  68. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/clarify_intent.impl.jac +0 -0
  69. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/clarify_intent.jac +0 -0
  70. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/think.impl.jac +0 -0
  71. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/think.jac +0 -0
  72. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/todo.impl.jac +0 -0
  73. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/meta/todo.jac +0 -0
  74. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/net/__init__.jac +0 -0
  75. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/net/preview.impl.jac +0 -0
  76. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/net/preview.jac +0 -0
  77. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/net/web.impl.jac +0 -0
  78. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/net/web.jac +0 -0
  79. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/__init__.jac +0 -0
  80. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/load_jac_skill.impl.jac +0 -0
  81. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/load_jac_skill.jac +0 -0
  82. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/search.impl.jac +0 -0
  83. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/read/search.jac +0 -0
  84. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/__init__.jac +0 -0
  85. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/guarded.impl.jac +0 -0
  86. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/guarded.jac +0 -0
  87. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/jac_tools.impl.jac +0 -0
  88. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/jac_tools.jac +0 -0
  89. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/run/shell.impl.jac +0 -0
  90. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/write/__init__.jac +0 -0
  91. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/tool/write/checked.jac +0 -0
  92. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/__init__.jac +0 -0
  93. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/banner.jac +0 -0
  94. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/colors.jac +0 -0
  95. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/md_render.jac +0 -0
  96. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/sandbox.impl.jac +0 -0
  97. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/sandbox.jac +0 -0
  98. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder/util/tool_output.jac +0 -0
  99. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder.egg-info/dependency_links.txt +0 -0
  100. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder.egg-info/entry_points.txt +0 -0
  101. {jac_coder-0.2.8 → jac_coder-0.2.9}/jac_coder.egg-info/top_level.txt +0 -0
  102. {jac_coder-0.2.8 → jac_coder-0.2.9}/setup.cfg +0 -0
@@ -1,10 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jac-coder
3
- Version: 0.2.8
3
+ Version: 0.2.9
4
4
  Summary: AI coding agent backend for Jac, powered by jac-byllm
5
5
  Requires-Python: >=3.12
6
6
  Requires-Dist: python-dotenv>=1.0.0
7
- Requires-Dist: jaclang
8
7
  Requires-Dist: mcp>=1.0.0
9
8
  Requires-Dist: jac-mcp
10
9
  Requires-Dist: rich>=13.0
10
+ Requires-Dist: litellm<=1.82.6,>=1.70.0
11
+ Requires-Dist: httpx>=0.27.0
12
+ Requires-Dist: loguru<0.8.0,>=0.7.2
13
+ Requires-Dist: pillow<13.0.0,>=12.0.0
@@ -64,7 +64,6 @@ Root → Session → MainAgent
64
64
  - **WorkerAgent (walker)** — in-process SubAgent with 14 tools (can write/edit/run). For known changes.
65
65
  - **ExplorerAgent (walker)** — in-process SubAgent with 10 tools (read-only + web search). For root-cause investigation.
66
66
  - **Session (node)** — persistent chat state, history, active files, errors, mode hint.
67
- - **ProjectMemory (node)** — AST-derived codebase knowledge (nodes, walkers, edges, imports). Backed by `.jaccoder/progress.md` as primary source of truth.
68
67
  - **McpRegistry (node)** — persisted MCP server configs.
69
68
 
70
69
  See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full picture.
@@ -130,7 +129,7 @@ jac-code/
130
129
  │ ├── api.jac # Public API — the only module external apps import
131
130
  │ ├── server.jac # JSON-RPC stdio server for the VS Code extension
132
131
  │ ├── core/
133
- │ │ ├── nodes.jac # MainAgent, WorkerAgent, ExplorerAgent, Session, ProjectMemory
132
+ │ │ ├── nodes.jac # MainAgent, WorkerAgent, ExplorerAgent, Session
134
133
  │ │ └── walkers.jac # interact, new_session, list_sessions, etc.
135
134
  │ ├── lib/
136
135
  │ │ └── coder.jac # JacCoder library-mode class (stateless + service modes)
@@ -140,7 +139,6 @@ jac-code/
140
139
  │ ├── runtime/
141
140
  │ │ ├── context.jac # Tiered compaction with LLM-summary fallback
142
141
  │ │ ├── events.jac # Event bus, doom-loop detection, abort signal
143
- │ │ ├── memory.jac # AST-first ProjectMemory (LLM fallback)
144
142
  │ │ ├── permission.jac # Permission rule engine (allow / ask / deny)
145
143
  │ │ ├── prompt.jac # Mode-aware dynamic prompt assembly
146
144
  │ │ ├── skills.jac # SKILL.md registry + listing injection
@@ -197,7 +197,6 @@ impl chat(
197
197
  return {"error": "Session is stale after a server update. Please close this session and open a new one.", "agent": "error"};
198
198
  }
199
199
 
200
- # Override directory if provided
201
200
  if directory {
202
201
  session.directory = directory;
203
202
  }
@@ -230,7 +229,6 @@ impl chat(
230
229
  # whether to auto-allow, prompt, or deny write/edit/bash operations.
231
230
  _set_chat_session(session_id, edit_mode);
232
231
 
233
- # Setup
234
232
  clear_abort();
235
233
  reset_steps();
236
234
  start_turn();
@@ -242,7 +240,6 @@ impl chat(
242
240
  }
243
241
 
244
242
  try {
245
- # Memory initialization
246
243
  _ensure_memory(session, work_dir);
247
244
 
248
245
  session.updated_at = datetime.now().isoformat();
@@ -367,7 +364,6 @@ impl chat(
367
364
  files_modified = summary.get("files_modified", []);
368
365
  has_errors = summary.get("errors", 0) > 0;
369
366
 
370
- # Update session state
371
367
  if files_modified {
372
368
  for f in files_modified {
373
369
  if f not in session.active_files {
@@ -483,63 +479,6 @@ def _ensure_memory(session: Session, work_dir: str) -> None {
483
479
  }
484
480
 
485
481
 
486
- def _post_process(session: Session, response_obj: Any) -> None {
487
- # Track files
488
- if response_obj.files_modified {
489
- for f in response_obj.files_modified {
490
- if f not in session.active_files {
491
- session.active_files.append(f);
492
- }
493
- }
494
- if len(session.active_files) > 10 {
495
- session.active_files = session.active_files[-10:];
496
- }
497
- }
498
-
499
- # Track errors
500
- if response_obj.has_errors {
501
- files_str = ", ".join(response_obj.files_modified)
502
- if response_obj.files_modified
503
- else "unknown";
504
- session.pending_errors = [f"Errors in previous turn (files: {files_str})"];
505
- } else {
506
- session.pending_errors = [];
507
- }
508
-
509
- # Refresh project_summary from progress.md (agent may have updated it).
510
- if session.directory {
511
- progress_path = os.path.join(session.directory, ".jaccoder", "progress.md");
512
- if os.path.isfile(progress_path) {
513
- try {
514
- with open(progress_path, "r", encoding="utf-8") as f {
515
- pc = f.read();
516
- }
517
- if len(pc) > 4000 {
518
- pc = pc[:4000] + "\n\n[... truncated]";
519
- }
520
- session.project_summary = pc;
521
- } except Exception { }
522
- }
523
- }
524
-
525
- # Persist response
526
- record: dict = {
527
- "role": "assistant",
528
- "content": response_obj.content,
529
- "agent": "main"
530
- };
531
- if response_obj.tools_used {
532
- record["tools_used"] = response_obj.tools_used;
533
- }
534
- if response_obj.files_modified {
535
- record["files_modified"] = response_obj.files_modified;
536
- }
537
- session.chat_history.append(record);
538
- session.last_agent = "main";
539
- session.updated_at = datetime.now().isoformat();
540
- }
541
-
542
-
543
482
  # ---------------------------------------------------------------------------
544
483
  # Model management API
545
484
  # ---------------------------------------------------------------------------
@@ -11,8 +11,7 @@ import from jac_coder.infra.config {
11
11
  }
12
12
  import from jac_coder.util.tool_output { tool_end }
13
13
  import from jac_coder.runtime.permission { permission_engine }
14
- import from jac_coder.util.sandbox { set_sandbox_root, set_browser_exec }
15
- import from jac_coder.runtime.context { build_context, ContextConfig }
14
+ import from jac_coder.util.sandbox { set_sandbox_root }
16
15
  import from jac_coder.core.walkers {
17
16
  new_session,
18
17
  ensure_main_agent,
@@ -28,11 +27,6 @@ import from jac_coder.infra.mcp_manager {
28
27
  mcp_get_tools,
29
28
  mcp_register_builtin
30
29
  }
31
- import from jac_coder.runtime.memory {
32
- find_or_create_memory,
33
- _init_memory,
34
- update_memory_from_session
35
- }
36
30
  import from jac_coder.core.nodes { Session, MainAgent }
37
31
  import from jac_coder.runtime.cost_tracker {
38
32
  get_summary as _ct_get_summary,
@@ -41,7 +35,6 @@ import from jac_coder.runtime.cost_tracker {
41
35
  import from jac_coder.tool.run.guarded {
42
36
  _set_chat_session,
43
37
  _clear_chat_session,
44
- _chat_contexts,
45
38
  _clarification_events,
46
39
  _clarification_decisions,
47
40
  _CLRFY_KEY_PREFIX
@@ -52,7 +45,6 @@ import from jac_coder.runtime.events {
52
45
  reset_steps,
53
46
  start_turn,
54
47
  emit_turn_summary,
55
- emit_event,
56
48
  is_abort_requested,
57
49
  clear_abort
58
50
  }
@@ -2,19 +2,15 @@
2
2
 
3
3
  import os;
4
4
  import sys;
5
- import from datetime { datetime }
6
5
  import from jac_coder.core.nodes { Session, MainAgent }
7
6
  import from jac_coder.core.walkers {
8
7
  new_session,
9
- list_sessions,
10
- get_session,
11
- close_session,
12
8
  interact,
13
9
  ensure_main_agent
14
10
  }
15
- import from jac_coder.infra.config { llm, model_name, get_config, set_model, get_model }
11
+ import from jac_coder.infra.config { model_name, get_config, set_model, get_model }
16
12
  import from jac_coder.runtime.permission { permission_engine }
17
- import from jac_coder.runtime.events { register_event_callback, get_agent_prefix }
13
+ import from jac_coder.runtime.events { register_event_callback }
18
14
  import from jac_coder.runtime.file_logger { init_file_logger, file_log_event, close_file_logger }
19
15
  import from jac_coder.tool.meta.todo { get_todos }
20
16
  import from jac_coder.util.colors {
@@ -26,7 +22,6 @@ import from jac_coder.util.colors {
26
22
  GREEN,
27
23
  YELLOW,
28
24
  RED,
29
- MAGENTA,
30
25
  WHITE,
31
26
  AGENT_COLORS
32
27
  }
@@ -14,68 +14,6 @@ impl Session.postinit{
14
14
  }
15
15
 
16
16
 
17
- # ---------------------------------------------------------------------------
18
- # ProjectMemory
19
- # ---------------------------------------------------------------------------
20
- sem ProjectMemory.profile_project = """Analyze a Jac project and extract structured memory.
21
- Given the file tree and key file contents, return:
22
- - architecture: 1-2 sentences describing the project purpose, tech stack, and node/walker structure
23
- - file_map: dict mapping up to 15 important file paths (relative) to 1-line descriptions of their role
24
- - conventions: list of coding conventions observed (naming style, file organization, patterns)
25
- Be concise and factual. This context will help future coding sessions start smart.""";
26
-
27
- sem ProjectMemory.collect_learnings = """Extract learnings from a completed coding session.
28
- Given the files modified and a session summary, return only NEW information:
29
- - new_files: dict of newly created or significantly changed file paths to 1-line descriptions
30
- - new_conventions: new coding patterns or conventions established (empty list if none)
31
- - new_decisions: architectural or design decisions made (empty list if none)
32
- - known_issues: bugs or issues discovered but not yet fixed (empty list if none)
33
- Be selective — only include genuinely new information.""";
34
-
35
- sem ProjectScan.architecture = "1-2 sentences: project purpose, tech stack, and overall node/walker structure";
36
- sem ProjectScan.file_map = "dict mapping relative file paths to 1-line role descriptions (max 15 files)";
37
- sem ProjectScan.conventions = "list of coding conventions: naming style, file organization, patterns used";
38
-
39
- sem SessionLearnings.new_files = "dict of new/modified file paths to 1-line descriptions of their content";
40
- sem SessionLearnings.new_conventions = "new coding conventions established this session (empty list if none)";
41
- sem SessionLearnings.new_decisions = "architectural decisions made this session (empty list if none)";
42
- sem SessionLearnings.known_issues = "bugs or issues discovered but not yet fixed (empty list if none)";
43
-
44
- impl ProjectMemory.summarize() -> str {
45
- parts = [];
46
- if self.architecture {
47
- parts.append("Architecture: " + self.architecture);
48
- }
49
- if self.node_details {
50
- parts.append(self.node_details);
51
- }
52
- if self.walker_details {
53
- parts.append(self.walker_details);
54
- }
55
- if self.graph_topology {
56
- parts.append("Graph: " + self.graph_topology);
57
- }
58
- if self.import_map {
59
- parts.append(self.import_map);
60
- }
61
- if self.file_map {
62
- items = list(self.file_map.items())[:10];
63
- file_lines = [f" {k}: {v}" for (k, v) in items];
64
- parts.append("Key files:\n" + "\n".join(file_lines));
65
- }
66
- if self.conventions {
67
- parts.append("Conventions: " + ", ".join(self.conventions[:5]));
68
- }
69
- if self.past_decisions {
70
- parts.append("Past decisions: " + "; ".join(self.past_decisions[:3]));
71
- }
72
- if self.known_issues {
73
- parts.append("Known issues: " + "; ".join(self.known_issues[:3]));
74
- }
75
- return "\n".join(parts);
76
- }
77
-
78
-
79
17
  # ---------------------------------------------------------------------------
80
18
  # MainAgent — the orchestrator
81
19
  # ---------------------------------------------------------------------------
@@ -1,4 +1,3 @@
1
- import os;
2
1
  import sys;
3
2
 
4
3
  import from uuid { uuid4 }
@@ -12,7 +11,7 @@ import from jac_coder.tool.meta.think { think }
12
11
  import from jac_coder.tool.meta.delegation { spawn_agent, set_iter_count }
13
12
  import from jac_coder.tool.meta.todo { update_todos }
14
13
  import from jac_coder.tool.read.load_jac_skill { load_jac_skill }
15
- import from jac_coder.tool.meta.clarify_intent { clarify_intent, ClarifyOption }
14
+ import from jac_coder.tool.meta.clarify_intent { clarify_intent }
16
15
  import from jac_coder.tool.net.web { web_fetch, web_search }
17
16
  import from jac_coder.tool.run.guarded { run_command }
18
17
  import from jac_coder.tool.run.jac_tools { jac_check, jac_run }
@@ -101,21 +100,6 @@ sem TurnReflection.smoothness = "0.0 (fought it for many iterations or left it u
101
100
  sem TurnReflection.category = "Pick the ONE category that best fits the struggle's root cause. skills_gap: you lacked the right Jac pattern and the skills/docs did not cover it. upstream_bug: a real bug or limitation in Jac/Jaseci/jac-cloud itself, not your own mistake. syntax_error: Jac or cl.jac syntax you got wrong. framework_api: you misunderstood a Jac/jac-cloud API or concept (persistence, walkers, nodes/edges, routing, auth). environment_issue: sandbox, deployment, install, or server/tooling environment problem. tooling_limitation: a JacCoder tool itself fell short (edit match failed, browser, etc.). logic_error: your own application logic/reasoning bug. ambiguity: the user request was unclear or underspecified. none: no significant struggle this turn.";
102
101
 
103
102
 
104
- obj ProjectScan {
105
- has architecture: str;
106
- has file_map: dict[str, str];
107
- has conventions: list[str];
108
- }
109
-
110
-
111
- obj SessionLearnings {
112
- has new_files: dict[str, str];
113
- has new_conventions: list[str];
114
- has new_decisions: list[str];
115
- has known_issues: list[str];
116
- }
117
-
118
-
119
103
  # ---------------------------------------------------------------------------
120
104
  # McpRegistry — persists MCP server configs in the graph
121
105
  # ---------------------------------------------------------------------------
@@ -134,35 +118,6 @@ node UserPermissionRules {
134
118
  }
135
119
 
136
120
 
137
- # ---------------------------------------------------------------------------
138
- # ProjectMemory — persists codebase knowledge across sessions
139
- # ---------------------------------------------------------------------------
140
- node ProjectMemory {
141
- has project_dir: str = "",
142
- architecture: str = "",
143
- file_map: dict[str, str] = {},
144
- conventions: list[str] = [],
145
- past_decisions: list[str] = [],
146
- known_issues: list[str] = [],
147
- graph_topology: str = "",
148
- node_details: str = "",
149
- walker_details: str = "",
150
- import_map: str = "",
151
- scan_attempted: bool = False,
152
- last_updated: str = "";
153
-
154
- def profile_project(file_tree: str, key_files: str) -> ProjectScan by llm(
155
- temperature=0.1
156
- );
157
-
158
- def collect_learnings(
159
- files_modified: list[str], session_summary: str
160
- ) -> SessionLearnings by llm(temperature=0.1);
161
-
162
- def summarize() -> str;
163
- }
164
-
165
-
166
121
  # ---------------------------------------------------------------------------
167
122
  # Session — persistent chat state
168
123
  # ---------------------------------------------------------------------------
@@ -168,7 +168,6 @@ impl interact.enter_session with Session entry {
168
168
  here.updated_at = datetime.now().isoformat();
169
169
  self.chat_history = here.chat_history;
170
170
 
171
- # Visit MainAgent
172
171
  visit [-->][?:MainAgent] else {
173
172
  agent = ensure_main_agent();
174
173
  here ++> agent;
@@ -3,17 +3,9 @@ import os;
3
3
  import from http { HTTPMethod }
4
4
  import from datetime { datetime }
5
5
  import from jac_coder.util.tool_output { tool_end }
6
- import from jac_coder.util.sandbox { set_sandbox_root }
7
- import from jac_coder.infra.config { llm, get_config }
6
+ import from jac_coder.infra.config { get_config }
8
7
  import from jaclang.runtimelib.builtin { restspec }
9
- import from jac_coder.runtime.context { build_context, ContextConfig }
10
8
  import from jac_coder.runtime.events { reset_steps, start_turn, emit_turn_summary, emit_event, clear_abort, is_abort_requested, emit_phase_change, emit_previewable }
11
- import from jaclang.byllm.types { StreamEvent }
12
- import from jac_coder.runtime.memory {
13
- find_or_create_memory,
14
- _init_memory,
15
- update_memory_from_session
16
- }
17
9
  import from jac_coder.core.nodes { Session, MainAgent, UIDesignerAgent }
18
10
 
19
11
 
@@ -2,7 +2,6 @@ import os;
2
2
  import json;
3
3
  import threading;
4
4
  import from contextlib { suppress }
5
- import from pathlib { Path }
6
5
  import from dotenv { load_dotenv }
7
6
  import from jaclang.byllm.lib { Model }
8
7
 
@@ -66,9 +66,21 @@ def _try_init() -> None {
66
66
  }
67
67
  _broker_init_done = True;
68
68
  try {
69
- import jac_scale.events.publisher as _pm;
70
- import from jac_scale.events.publisher { publish as _pub }
71
- import from jac_scale.events.broker { Event as _Ev }
69
+ # jac-scale was folded into core jaclang (jaseci#7034), so the runtime
70
+ # module is `jaclang.scale.*`. Prefer that; fall back to the standalone
71
+ # `jac_scale.*` for pre-fold binaries. Without this, the import fails on a
72
+ # folded runtime ("No module named 'jac_scale'"), the broker never wires,
73
+ # and a stream_events() call that load-balances onto a peer pod raises
74
+ # "run_id not found" (run_turn registered the run on a different replica).
75
+ try {
76
+ import jaclang.scale.events.publisher as _pm;
77
+ import from jaclang.scale.events.publisher { publish as _pub }
78
+ import from jaclang.scale.events.broker { Event as _Ev }
79
+ } except Exception {
80
+ import jac_scale.events.publisher as _pm;
81
+ import from jac_scale.events.publisher { publish as _pub }
82
+ import from jac_scale.events.broker { Event as _Ev }
83
+ }
72
84
  _pub_mod = _pm;
73
85
  _publish_fn = _pub;
74
86
  _Event = _Ev;
@@ -42,7 +42,16 @@ def _try_init() -> None {
42
42
  }
43
43
  _kv_init_done = True;
44
44
  try {
45
- import from jac_scale.lib { kvstore }
45
+ # jac-scale folded into core jaclang (jaseci#7034): kvstore now lives
46
+ # at jaclang.scale.persistence.lib. Prefer it; fall back to the
47
+ # standalone jac_scale.lib for pre-fold binaries. Without this the
48
+ # cross-pod KV cache silently disables on a folded runtime
49
+ # ("No module named 'jac_scale'").
50
+ try {
51
+ import from jaclang.scale.persistence.lib { kvstore }
52
+ } except Exception {
53
+ import from jac_scale.lib { kvstore }
54
+ }
46
55
  _kv = kvstore(db_name="jac_coder", db_type="redis");
47
56
  } except Exception as e {
48
57
  # Redis not configured — common in CLI/stdio mode and local dev.
@@ -12,7 +12,6 @@ Supported transport types:
12
12
 
13
13
  import os;
14
14
  import json;
15
- import time;
16
15
 
17
16
  import from urllib.request { urlopen, Request }
18
17
  import from importlib.metadata { version }
@@ -11,7 +11,7 @@ import logging;
11
11
  import from uuid { uuid4 }
12
12
  import from queue { Queue, Empty }
13
13
  import from datetime { datetime, timezone }
14
- import from typing { Any, Iterator, Callable }
14
+ import from typing { Any, Callable }
15
15
 
16
16
  import from jac_coder.core.nodes { Session, Run }
17
17
  import from jac_coder.api {
@@ -14,7 +14,7 @@ import logging;
14
14
  import from uuid { uuid4 }
15
15
  import from queue { Queue, Empty }
16
16
  import from datetime { datetime, timezone }
17
- import from typing { Any, Iterator }
17
+ import from typing { Any }
18
18
 
19
19
 
20
20
  glob _logger: logging.Logger = logging.getLogger("jac_coder.lib");
@@ -10,8 +10,8 @@ def _build_prefix(
10
10
  ) -> list[dict] {
11
11
  parts = [];
12
12
  if project_summary {
13
- # project_summary comes from .jaccoder/progress.md (preferred) or ProjectMemory
14
- # This is the agent's persistent knowledge of the project state.
13
+ # project_summary comes from .jaccoder/progress.md the agent's
14
+ # persistent knowledge of the project state.
15
15
  is_progress_file = project_summary.lstrip().startswith("#");
16
16
  label = "Project progress (.jaccoder/progress.md)" if is_progress_file else "Project context";
17
17
  parts.append(f"[INTERNAL — do NOT present this to the user unless they ask about the project. This is your background knowledge for making informed decisions.]\n{label}:\n{project_summary}");
@@ -27,13 +27,11 @@ impl record_usage(usage_data: dict, agent: str = "main") -> None {
27
27
  ),
28
28
  "total_tokens": int(call.get("total_tokens", 0) or 0)
29
29
  };
30
- # Calculate total if not provided
31
30
  if not call_record["total_tokens"] {
32
31
  call_record["total_tokens"] = call_record["input_tokens"] + call_record["output_tokens"];
33
32
  }
34
33
  state["calls"].append(call_record);
35
34
 
36
- # Accumulate into running totals from this call
37
35
  state["totals"]["input_tokens"] += call_record["input_tokens"];
38
36
  state["totals"]["output_tokens"] += call_record["output_tokens"];
39
37
  state["totals"]["cached_tokens"] += call_record["cached_tokens"];
@@ -21,12 +21,6 @@ glob _log_turn_cost: dict = {}; # float accumulator per session_id
21
21
  glob _log_lock: threading.Lock = threading.Lock();
22
22
 
23
23
 
24
- """True when JACCODER_LOG=1 is set and logger is initialized."""
25
- def is_logging_enabled() -> bool {
26
- return bool(_log_file_handle);
27
- }
28
-
29
-
30
24
  """Initialize the file logger. No-op if JACCODER_LOG is not set.
31
25
 
32
26
  Call once at startup. Safe to call multiple times — only initializes once.
@@ -9,8 +9,7 @@ impl PermissionEngine.init_defaults() -> None {
9
9
  "clarify_intent",
10
10
  "update_todos",
11
11
  "jac_check",
12
- "jac_run",
13
- "spawn_task"
12
+ "jac_run"
14
13
  ] {
15
14
  self.rules.append(PermissionRule(tool=tool, action="allow"));
16
15
  }
@@ -11,10 +11,6 @@ impl compose_system_prompt_filtered(base_prompt: str, allowed_skills: set[str])
11
11
  return (base_prompt + "\n\n" + skills_block) if skills_block else base_prompt;
12
12
  }
13
13
 
14
- impl smells_like_build(message: str) -> bool {
15
- return _smells_like_build(message);
16
- }
17
-
18
14
  # ---------------------------------------------------------------------------
19
15
  # infer_mode_hint — classify what the agent did from ground truth
20
16
  # ---------------------------------------------------------------------------
@@ -212,5 +212,3 @@ def compose_system_prompt(base_prompt: str) -> str;
212
212
  """Like compose_system_prompt but only includes skills listed in `allowed_skills`. Used by per-agent prompts."""
213
213
  def compose_system_prompt_filtered(base_prompt: str, allowed_skills: set[str]) -> str;
214
214
 
215
- """Public wrapper for the private _smells_like_build check."""
216
- def smells_like_build(message: str) -> bool;
@@ -37,9 +37,6 @@ the body when needed.
37
37
  import os;
38
38
 
39
39
 
40
- glob DEFAULT_SKILLS_DIRNAME: str = "skills";
41
-
42
-
43
40
  obj SkillMeta {
44
41
  has name: str; # unique skill id — matches filename stem
45
42
  has description: str; # one-line match target for the model
@@ -7,7 +7,6 @@ import from jac_coder.tool.net.web { web_fetch, web_search }
7
7
  import from jac_coder.tool.read.search { grep_search, find_files }
8
8
  import from jac_coder.tool.meta.todo { update_todos, get_todos }
9
9
  import from jac_coder.tool.run.jac_tools { jac_check, jac_run }
10
- import from jac_coder.tool.meta.validate { validate_project }
11
10
  import from jac_coder.tool.git { git_status, git_diff, git_commit, git_log }
12
11
  import from jac_coder.tool.write.checked { write_code, edit_code, delete_code }
13
12
  import from jac_coder.tool.run.guarded { write_file_guarded, edit_file_guarded, delete_file_guarded, run_command }
@@ -64,7 +64,6 @@ impl git_commit(message: str, files: list[str] = [], directory: str = "") -> str
64
64
  return "Error: commit message is required.";
65
65
  }
66
66
 
67
- # Stage files
68
67
  if files {
69
68
  for fp in files {
70
69
  (_, err, code) = _run_git(["add", fp], directory);
@@ -81,7 +80,6 @@ impl git_commit(message: str, files: list[str] = [], directory: str = "") -> str
81
80
  }
82
81
  }
83
82
 
84
- # Commit
85
83
  (out, err, code) = _run_git(["commit", "-m", message], directory);
86
84
  if code != 0 {
87
85
  if "nothing to commit" in (out + err) {
@@ -109,7 +109,6 @@ impl spawn_agent(task: str, mode: str = "worker") -> str {
109
109
  return "Error: Iteration budget exhausted. Cannot spawn more SubAgents.";
110
110
  }
111
111
 
112
- # Enrich task with session context
113
112
  project_ctx = get_project_summary_for_subagent();
114
113
  recent_work = get_recent_results_summary();
115
114
  clarification_ctx = _get_clarification_context();
@@ -161,7 +160,6 @@ impl spawn_agent(task: str, mode: str = "worker") -> str {
161
160
  has_errs = len(errs) > 0;
162
161
  iters_used = getattr(_tl, "iter_count", len(used_tools));
163
162
 
164
- # Track budget and state
165
163
  consume_budget(iters_used);
166
164
  for fp in fmod {
167
165
  track_file(fp);
@@ -181,7 +179,6 @@ impl spawn_agent(task: str, mode: str = "worker") -> str {
181
179
  }
182
180
  );
183
181
 
184
- # Build result string
185
182
  result_parts: list = [];
186
183
  if content {
187
184
  result_parts.append(content);
@@ -2,7 +2,7 @@ import threading;
2
2
 
3
3
  import from jac_coder.infra.config { get_config }
4
4
  import from jac_coder.util.tool_output { tool_status, tool_end }
5
- import from jac_coder.runtime.events { track_file, track_error, emit_event }
5
+ import from jac_coder.runtime.events { track_file, track_error }
6
6
 
7
7
 
8
8
  glob _tl: Any = threading.local();
@@ -683,7 +683,6 @@ impl write_file(file_path: str, content: str) -> str {
683
683
  fix_count = len(auto_fixes);
684
684
  result_msg = f"OK: {short_name} ({line_count} lines" + (f", {fix_count} auto-fixes" if fix_count else "") + ")";
685
685
 
686
- # Write succeeded
687
686
  tool_end(f"-> {line_count} lines");
688
687
 
689
688
  # Stage 2: Compiler validation (separate step so errors show on "Check", not "Write")
@@ -779,7 +778,6 @@ impl edit_file(
779
778
  fix_count = len(auto_fixes);
780
779
  result_msg = f"OK: {short_name} ({replacements} edit" + ("s" if replacements > 1 else "") + (f", {fix_count} auto-fixes" if fix_count else "") + ")";
781
780
 
782
- # Edit succeeded
783
781
  tool_end(f"-> {replacements} edit(s)");
784
782
 
785
783
  # Stage 2: Compiler validation (separate step)
@@ -1,7 +1,6 @@
1
1
  import os;
2
2
  import re;
3
3
  import time;
4
- import subprocess;
5
4
  import mimetypes;
6
5
 
7
6
  import from pathlib { Path }