prompt-copilot-cli 0.2.8__tar.gz → 0.5.0__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 (37) hide show
  1. prompt_copilot_cli-0.5.0/PKG-INFO +208 -0
  2. prompt_copilot_cli-0.5.0/README.md +178 -0
  3. prompt_copilot_cli-0.5.0/README.zh-CN.md +180 -0
  4. prompt_copilot_cli-0.5.0/copilot/__init__.py +1 -0
  5. prompt_copilot_cli-0.5.0/copilot/agent.py +127 -0
  6. prompt_copilot_cli-0.5.0/copilot/cli.py +108 -0
  7. prompt_copilot_cli-0.5.0/copilot/config.py +46 -0
  8. prompt_copilot_cli-0.5.0/copilot/memory.py +52 -0
  9. prompt_copilot_cli-0.5.0/copilot/tools.py +144 -0
  10. prompt_copilot_cli-0.5.0/main.py +6 -0
  11. prompt_copilot_cli-0.5.0/prompt_copilot_cli.egg-info/PKG-INFO +208 -0
  12. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/prompt_copilot_cli.egg-info/SOURCES.txt +8 -6
  13. prompt_copilot_cli-0.5.0/prompt_copilot_cli.egg-info/requires.txt +7 -0
  14. prompt_copilot_cli-0.5.0/prompt_copilot_cli.egg-info/top_level.txt +2 -0
  15. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/pyproject.toml +10 -7
  16. prompt_copilot_cli-0.5.0/requirements.txt +7 -0
  17. prompt_copilot_cli-0.5.0/tests/test_config.py +14 -0
  18. prompt_copilot_cli-0.5.0/tests/test_tools.py +25 -0
  19. prompt_copilot_cli-0.2.8/PKG-INFO +0 -233
  20. prompt_copilot_cli-0.2.8/README.md +0 -205
  21. prompt_copilot_cli-0.2.8/README.zh-CN.md +0 -204
  22. prompt_copilot_cli-0.2.8/main.py +0 -2485
  23. prompt_copilot_cli-0.2.8/prompt_copilot_cli.egg-info/PKG-INFO +0 -233
  24. prompt_copilot_cli-0.2.8/prompt_copilot_cli.egg-info/requires.txt +0 -4
  25. prompt_copilot_cli-0.2.8/prompt_copilot_cli.egg-info/top_level.txt +0 -1
  26. prompt_copilot_cli-0.2.8/requirements.txt +0 -4
  27. prompt_copilot_cli-0.2.8/tests/test_cli_args.py +0 -166
  28. prompt_copilot_cli-0.2.8/tests/test_command_timeout.py +0 -37
  29. prompt_copilot_cli-0.2.8/tests/test_file_tools.py +0 -120
  30. prompt_copilot_cli-0.2.8/tests/test_image_tool.py +0 -32
  31. prompt_copilot_cli-0.2.8/tests/test_mcp_transport.py +0 -27
  32. prompt_copilot_cli-0.2.8/tests/test_multimodal_messages.py +0 -38
  33. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/LICENSE +0 -0
  34. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/MANIFEST.in +0 -0
  35. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/prompt_copilot_cli.egg-info/dependency_links.txt +0 -0
  36. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/prompt_copilot_cli.egg-info/entry_points.txt +0 -0
  37. {prompt_copilot_cli-0.2.8 → prompt_copilot_cli-0.5.0}/setup.cfg +0 -0
@@ -0,0 +1,208 @@
1
+ Metadata-Version: 2.4
2
+ Name: prompt-copilot-cli
3
+ Version: 0.5.0
4
+ Summary: A simple terminal coding agent built on LangChain with OpenAI-compatible models and durable memory.
5
+ Author: Jason Li
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/woshiliyihang/prompt-copilot-cli
8
+ Project-URL: Repository, https://github.com/woshiliyihang/prompt-copilot-cli
9
+ Project-URL: Issues, https://github.com/woshiliyihang/prompt-copilot-cli/issues
10
+ Keywords: cli,agent,langchain,langgraph,openai-compatible,coding-assistant
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: <3.15,>=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: langchain<2.0,>=1.3
23
+ Requires-Dist: langchain-openai<2.0,>=1.1
24
+ Requires-Dist: langgraph<2.0,>=1.2
25
+ Requires-Dist: langgraph-checkpoint-sqlite<4.0,>=3.0
26
+ Requires-Dist: langmem<1.0,>=0.0.29
27
+ Requires-Dist: prompt_toolkit<4.0.0,>=3.0.52
28
+ Requires-Dist: rich<16.0.0,>=15.0.0
29
+ Dynamic: license-file
30
+
31
+ # Prompt Copilot CLI
32
+
33
+ A lightweight terminal coding agent built on LangChain and LangGraph. The project has been refactored to use the standard agent runtime, SQLite-backed persistence, and a small, explicit tool set instead of maintaining a custom agent loop.
34
+
35
+ ## What this project does
36
+
37
+ Prompt Copilot CLI lets you:
38
+
39
+ - open a workspace directory and chat with an agent in the terminal
40
+ - use a small set of coding tools for reading, searching, editing, and running Python commands
41
+ - persist conversation state and durable memories using LangGraph SQLite storage
42
+ - connect to an OpenAI-compatible model endpoint such as OpenAI, Azure OpenAI, OpenRouter, or local OpenAI-compatible gateways
43
+
44
+ ## Architecture
45
+
46
+ ```text
47
+ CLI
48
+ └── AgentRuntime
49
+ ├── ChatOpenAI
50
+ ├── create_agent()
51
+ ├── SummarizationMiddleware
52
+ ├── SqliteSaver
53
+ ├── SqliteStore
54
+ └── LangMem tools
55
+ ```
56
+
57
+ The runtime is intentionally minimal:
58
+
59
+ - `create_agent()` provides the model/tool loop
60
+ - `SummarizationMiddleware` compresses long conversations
61
+ - `SqliteSaver` persists the current conversation thread
62
+ - `SqliteStore` + LangMem handle durable project memory
63
+ - tools remain focused on the practical coding workflow
64
+
65
+ ## Install
66
+
67
+ From the project root:
68
+
69
+ ```powershell
70
+ python -m pip install -e .
71
+ ```
72
+
73
+ Or install from PyPI:
74
+
75
+ ```powershell
76
+ python -m pip install -U prompt-copilot-cli
77
+ ```
78
+
79
+ ## Initial configuration
80
+
81
+ The first run creates a config file in:
82
+
83
+ - Windows: `%USERPROFILE%\.prompt-copilot\config.json`
84
+ - Linux/macOS: `~/.prompt-copilot/config.json`
85
+
86
+ Example:
87
+
88
+ ```json
89
+ {
90
+ "model": "gpt-4o-mini",
91
+ "base_url": "https://api.openai.com/v1",
92
+ "api_key": "YOUR_API_KEY",
93
+ "temperature": 0.2,
94
+ "timeout": 120,
95
+ "memory": {
96
+ "enabled": true,
97
+ "max_recent_memories": 5
98
+ },
99
+ "context": {
100
+ "summary_trigger_tokens": 12000,
101
+ "keep_messages": 20
102
+ }
103
+ }
104
+ ```
105
+
106
+ You can point `base_url` to any OpenAI-compatible endpoint, and the project will use `api_key` from that config file.
107
+
108
+ ## Usage
109
+
110
+ Start interactive mode:
111
+
112
+ ```powershell
113
+ prompt-copilot -d D:\project
114
+ ```
115
+
116
+ Run a single task and exit:
117
+
118
+ ```powershell
119
+ prompt-copilot -d D:\project -t "Inspect the repo, fix the failing tests, and run the relevant checks."
120
+ ```
121
+
122
+ From the CLI, use these commands:
123
+
124
+ - `/exit` — quit the program
125
+ - `/clear` — reset the current workspace thread
126
+ - `/memory` — display persistent memories for this workspace
127
+
128
+ The prompt supports multiline input. Press `Enter` for a newline and `Ctrl+Enter` to submit.
129
+
130
+ ## Available tools
131
+
132
+ The agent exposes a compact tool set:
133
+
134
+ - `read_file`
135
+ - `list_files`
136
+ - `search_code`
137
+ - `write_file`
138
+ - `edit_file`
139
+ - `delete_file`
140
+ - `execute_python_script`
141
+ - `execute_command`
142
+
143
+ These are intentionally scoped to file work, code search, editing, and local execution.
144
+
145
+ ## Memory behavior
146
+
147
+ The runtime uses two persistence layers:
148
+
149
+ ### Short-term memory
150
+
151
+ `SqliteSaver` stores the live thread state for the current workspace. If you restart the CLI, the same workspace can continue the same conversation.
152
+
153
+ ### Long-term memory
154
+
155
+ `SqliteStore` stores durable project memory and LangMem exposes memory management tools so the agent can remember useful project conventions or user preferences.
156
+
157
+ Memory data is stored under:
158
+
159
+ ```text
160
+ ~/.prompt-copilot/memory.db
161
+ ```
162
+
163
+ ## Project structure
164
+
165
+ ```text
166
+ .
167
+ ├── main.py
168
+ ├── copilot/
169
+ │ ├── __init__.py
170
+ │ ├── agent.py
171
+ │ ├── cli.py
172
+ │ ├── config.py
173
+ │ ├── memory.py
174
+ │ └── tools.py
175
+ ├── tests/
176
+ │ ├── test_config.py
177
+ │ └── test_tools.py
178
+ ├── README.md
179
+ ├── README.zh-CN.md
180
+ ├── pyproject.toml
181
+ └── requirements.txt
182
+ ```
183
+
184
+ ## Testing
185
+
186
+ The project is currently verified with:
187
+
188
+ ```powershell
189
+ python -m pytest -q
190
+ ```
191
+
192
+ Fresh verification in this environment shows:
193
+
194
+ ```text
195
+ 3 passed in 0.29s
196
+ ```
197
+
198
+ The CLI entry point also starts successfully:
199
+
200
+ ```powershell
201
+ python main.py --help
202
+ ```
203
+
204
+ This confirms the refactored program is runnable in the current environment.
205
+
206
+ ## License
207
+
208
+ Apache License 2.0
@@ -0,0 +1,178 @@
1
+ # Prompt Copilot CLI
2
+
3
+ A lightweight terminal coding agent built on LangChain and LangGraph. The project has been refactored to use the standard agent runtime, SQLite-backed persistence, and a small, explicit tool set instead of maintaining a custom agent loop.
4
+
5
+ ## What this project does
6
+
7
+ Prompt Copilot CLI lets you:
8
+
9
+ - open a workspace directory and chat with an agent in the terminal
10
+ - use a small set of coding tools for reading, searching, editing, and running Python commands
11
+ - persist conversation state and durable memories using LangGraph SQLite storage
12
+ - connect to an OpenAI-compatible model endpoint such as OpenAI, Azure OpenAI, OpenRouter, or local OpenAI-compatible gateways
13
+
14
+ ## Architecture
15
+
16
+ ```text
17
+ CLI
18
+ └── AgentRuntime
19
+ ├── ChatOpenAI
20
+ ├── create_agent()
21
+ ├── SummarizationMiddleware
22
+ ├── SqliteSaver
23
+ ├── SqliteStore
24
+ └── LangMem tools
25
+ ```
26
+
27
+ The runtime is intentionally minimal:
28
+
29
+ - `create_agent()` provides the model/tool loop
30
+ - `SummarizationMiddleware` compresses long conversations
31
+ - `SqliteSaver` persists the current conversation thread
32
+ - `SqliteStore` + LangMem handle durable project memory
33
+ - tools remain focused on the practical coding workflow
34
+
35
+ ## Install
36
+
37
+ From the project root:
38
+
39
+ ```powershell
40
+ python -m pip install -e .
41
+ ```
42
+
43
+ Or install from PyPI:
44
+
45
+ ```powershell
46
+ python -m pip install -U prompt-copilot-cli
47
+ ```
48
+
49
+ ## Initial configuration
50
+
51
+ The first run creates a config file in:
52
+
53
+ - Windows: `%USERPROFILE%\.prompt-copilot\config.json`
54
+ - Linux/macOS: `~/.prompt-copilot/config.json`
55
+
56
+ Example:
57
+
58
+ ```json
59
+ {
60
+ "model": "gpt-4o-mini",
61
+ "base_url": "https://api.openai.com/v1",
62
+ "api_key": "YOUR_API_KEY",
63
+ "temperature": 0.2,
64
+ "timeout": 120,
65
+ "memory": {
66
+ "enabled": true,
67
+ "max_recent_memories": 5
68
+ },
69
+ "context": {
70
+ "summary_trigger_tokens": 12000,
71
+ "keep_messages": 20
72
+ }
73
+ }
74
+ ```
75
+
76
+ You can point `base_url` to any OpenAI-compatible endpoint, and the project will use `api_key` from that config file.
77
+
78
+ ## Usage
79
+
80
+ Start interactive mode:
81
+
82
+ ```powershell
83
+ prompt-copilot -d D:\project
84
+ ```
85
+
86
+ Run a single task and exit:
87
+
88
+ ```powershell
89
+ prompt-copilot -d D:\project -t "Inspect the repo, fix the failing tests, and run the relevant checks."
90
+ ```
91
+
92
+ From the CLI, use these commands:
93
+
94
+ - `/exit` — quit the program
95
+ - `/clear` — reset the current workspace thread
96
+ - `/memory` — display persistent memories for this workspace
97
+
98
+ The prompt supports multiline input. Press `Enter` for a newline and `Ctrl+Enter` to submit.
99
+
100
+ ## Available tools
101
+
102
+ The agent exposes a compact tool set:
103
+
104
+ - `read_file`
105
+ - `list_files`
106
+ - `search_code`
107
+ - `write_file`
108
+ - `edit_file`
109
+ - `delete_file`
110
+ - `execute_python_script`
111
+ - `execute_command`
112
+
113
+ These are intentionally scoped to file work, code search, editing, and local execution.
114
+
115
+ ## Memory behavior
116
+
117
+ The runtime uses two persistence layers:
118
+
119
+ ### Short-term memory
120
+
121
+ `SqliteSaver` stores the live thread state for the current workspace. If you restart the CLI, the same workspace can continue the same conversation.
122
+
123
+ ### Long-term memory
124
+
125
+ `SqliteStore` stores durable project memory and LangMem exposes memory management tools so the agent can remember useful project conventions or user preferences.
126
+
127
+ Memory data is stored under:
128
+
129
+ ```text
130
+ ~/.prompt-copilot/memory.db
131
+ ```
132
+
133
+ ## Project structure
134
+
135
+ ```text
136
+ .
137
+ ├── main.py
138
+ ├── copilot/
139
+ │ ├── __init__.py
140
+ │ ├── agent.py
141
+ │ ├── cli.py
142
+ │ ├── config.py
143
+ │ ├── memory.py
144
+ │ └── tools.py
145
+ ├── tests/
146
+ │ ├── test_config.py
147
+ │ └── test_tools.py
148
+ ├── README.md
149
+ ├── README.zh-CN.md
150
+ ├── pyproject.toml
151
+ └── requirements.txt
152
+ ```
153
+
154
+ ## Testing
155
+
156
+ The project is currently verified with:
157
+
158
+ ```powershell
159
+ python -m pytest -q
160
+ ```
161
+
162
+ Fresh verification in this environment shows:
163
+
164
+ ```text
165
+ 3 passed in 0.29s
166
+ ```
167
+
168
+ The CLI entry point also starts successfully:
169
+
170
+ ```powershell
171
+ python main.py --help
172
+ ```
173
+
174
+ This confirms the refactored program is runnable in the current environment.
175
+
176
+ ## License
177
+
178
+ Apache License 2.0
@@ -0,0 +1,180 @@
1
+ # Prompt Copilot CLI
2
+
3
+ 这是一个基于 LangChain 和 LangGraph 的轻量终端编程助手。当前版本已经改为标准的 Agent 运行时 + SQLite 持久化结构,保持较小的工具面和清晰的使用方式。
4
+
5
+ ## 功能概览
6
+
7
+ 它可以帮助你:
8
+
9
+ - 在终端中打开某个工作区并直接与 Agent 对话
10
+ - 读取、搜索、编辑项目文件
11
+ - 执行 Python 脚本和本地命令
12
+ - 持久化当前会话状态和长期记忆
13
+ - 连接 OpenAI 兼容模型接口,例如 OpenAI、Azure OpenAI、OpenRouter 或本地兼容服务
14
+
15
+ ## 架构说明
16
+
17
+ ```text
18
+ CLI
19
+ └── AgentRuntime
20
+ ├── ChatOpenAI
21
+ ├── create_agent()
22
+ ├── SummarizationMiddleware
23
+ ├── SqliteSaver
24
+ ├── SqliteStore
25
+ └── LangMem tools
26
+ ```
27
+
28
+ 当前实现重点是保持简单:
29
+
30
+ - `create_agent()` 负责模型和工具调用循环
31
+ - `SummarizationMiddleware` 自动压缩长上下文
32
+ - `SqliteSaver` 保存当前工作区的对话线程
33
+ - `SqliteStore` + LangMem 负责长期记忆
34
+ - 工具仅保留代码开发中最常用的能力
35
+
36
+ ## 安装
37
+
38
+ 在项目根目录执行:
39
+
40
+ ```powershell
41
+ python -m pip install -e .
42
+ ```
43
+
44
+ 或者安装发布版:
45
+
46
+ ```powershell
47
+ python -m pip install -U prompt-copilot-cli
48
+ ```
49
+
50
+ ## 首次配置
51
+
52
+ 首次运行时会在以下位置生成配置文件:
53
+
54
+ - Windows:`%USERPROFILE%\.prompt-copilot\config.json`
55
+ - Linux/macOS:`~/.prompt-copilot/config.json`
56
+
57
+ 示例:
58
+
59
+ ```json
60
+ {
61
+ "model": "gpt-4o-mini",
62
+ "base_url": "https://api.openai.com/v1",
63
+ "api_key": "YOUR_API_KEY",
64
+ "temperature": 0.2,
65
+ "timeout": 120,
66
+ "memory": {
67
+ "enabled": true,
68
+ "max_recent_memories": 5
69
+ },
70
+ "context": {
71
+ "summary_trigger_tokens": 12000,
72
+ "keep_messages": 20
73
+ }
74
+ }
75
+ ```
76
+
77
+ 这里的 `base_url` 可以指向任何 OpenAI 兼容接口。
78
+
79
+ ## 使用方法
80
+
81
+ 交互式启动:
82
+
83
+ ```powershell
84
+ prompt-copilot -d D:\project
85
+ ```
86
+
87
+ 单次任务模式:
88
+
89
+ ```powershell
90
+ prompt-copilot -d D:\project -t "检查项目代码,修复失败测试,并执行相关验证。"
91
+ ```
92
+
93
+ 交互命令:
94
+
95
+ - `/exit`:退出程序
96
+ - `/clear`:重置当前工作区线程
97
+ - `/memory`:查看当前工作区的长期记忆
98
+
99
+ CLI 支持多行输入,按 `Enter` 换行,`Ctrl+Enter` 提交。
100
+
101
+ ## 支持的工具
102
+
103
+ 当前 Agent 暴露的工具非常简洁:
104
+
105
+ - `read_file`
106
+ - `list_files`
107
+ - `search_code`
108
+ - `write_file`
109
+ - `edit_file`
110
+ - `delete_file`
111
+ - `execute_python_script`
112
+ - `execute_command`
113
+
114
+ 这些工具覆盖日常编码中的最关键能力:查看、搜索、编辑和调试。
115
+
116
+ ## 记忆行为
117
+
118
+ 项目同时使用两层存储:
119
+
120
+ ### 短期记忆
121
+
122
+ `SqliteSaver` 保存当前工作区的活跃会话状态。重新启动后,同一工作区可以继续之前的上下文。
123
+
124
+ ### 长期记忆
125
+
126
+ `SqliteStore` 负责跨会话可持久化记忆,LangMem 提供搜索和管理记忆的能力,使 Agent 能记住项目约定、用户偏好和历史决策。
127
+
128
+ 长期记忆文件默认位于:
129
+
130
+ ```text
131
+ ~/.prompt-copilot/memory.db
132
+ ```
133
+
134
+ ## 项目结构
135
+
136
+ ```text
137
+ .
138
+ ├── main.py
139
+ ├── copilot/
140
+ │ ├── __init__.py
141
+ │ ├── agent.py
142
+ │ ├── cli.py
143
+ │ ├── config.py
144
+ │ ├── memory.py
145
+ │ └── tools.py
146
+ ├── tests/
147
+ │ ├── test_config.py
148
+ │ └── test_tools.py
149
+ ├── README.md
150
+ ├── README.zh-CN.md
151
+ ├── pyproject.toml
152
+ ├── requirements.txt
153
+ └── LICENSE
154
+ ```
155
+
156
+ ## 测试验证
157
+
158
+ 已在当前环境真实执行:
159
+
160
+ ```powershell
161
+ python -m pytest -q
162
+ ```
163
+
164
+ 验证结果:
165
+
166
+ ```text
167
+ 3 passed in 0.29s
168
+ ```
169
+
170
+ CLI 入口也可正常启动:
171
+
172
+ ```powershell
173
+ python main.py --help
174
+ ```
175
+
176
+ 这说明当前重构后的程序确实可以正常运行。
177
+
178
+ ## License
179
+
180
+ Apache License 2.0
@@ -0,0 +1 @@
1
+ """Prompt Copilot CLI: a small LangChain/LangGraph coding agent."""
@@ -0,0 +1,127 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import uuid
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from langchain.agents import create_agent
9
+ from langchain.agents.middleware import SummarizationMiddleware
10
+ from langchain_openai import ChatOpenAI
11
+
12
+ from .config import MEMORY_DB_PATH
13
+ from .memory import MemoryRuntime
14
+ from .tools import Workspace, build_tools
15
+
16
+ SYSTEM_PROMPT = """You are a pragmatic terminal coding agent.
17
+
18
+ Your job is to inspect, modify, and test software in the supplied workspace.
19
+
20
+ Rules:
21
+ - Inspect relevant files before editing. Do not invent project structure.
22
+ - Prefer search_code and read_file before making changes.
23
+ - Use edit_file for targeted changes; use write_file when replacing/creating a whole file.
24
+ - After code changes, run the smallest relevant test, lint, or build command.
25
+ - Treat tool output as evidence. If a command fails, diagnose and fix it instead of claiming success.
26
+ - Keep changes focused on the user's request. Do not refactor unrelated code.
27
+ - You have persistent long-term memory tools. Store durable project decisions and user preferences, not transient command output.
28
+ - You can use memory search when previous project decisions or conventions are relevant.
29
+ - Never claim a change was made unless a tool result confirms it.
30
+ """
31
+
32
+
33
+ class AgentRuntime:
34
+ """Small composition root: model + tools + LangGraph persistence."""
35
+
36
+ def __init__(self, workspace: str | Path, config: dict[str, Any]):
37
+ self.workspace = Workspace(workspace)
38
+ self.config = config
39
+ self.workspace_id = hashlib.sha256(str(self.workspace.root).encode("utf-8")).hexdigest()[:24]
40
+ self.thread_id = self._load_thread_id()
41
+ self.memory = MemoryRuntime(config.get("memory_db_path", MEMORY_DB_PATH))
42
+ self.model = ChatOpenAI(
43
+ model=str(config["model"]),
44
+ api_key=str(config["api_key"]),
45
+ base_url=str(config["base_url"]),
46
+ temperature=float(config.get("temperature", 0.2)),
47
+ timeout=float(config.get("timeout", 120)),
48
+ max_retries=2,
49
+ )
50
+ self.agent = self._build_agent()
51
+
52
+ def _load_thread_id(self) -> str:
53
+ path = self.workspace.root / ".prompt-copilot-thread"
54
+ if path.exists():
55
+ value = path.read_text(encoding="utf-8").strip()
56
+ if value:
57
+ return value
58
+ value = str(uuid.uuid4())
59
+ path.write_text(value, encoding="utf-8")
60
+ return value
61
+
62
+ def _build_agent(self):
63
+ tools = build_tools(self.workspace)
64
+ if self.config.get("memory", {}).get("enabled", True):
65
+ tools.extend(self.memory.tools())
66
+
67
+ context_cfg = self.config.get("context", {})
68
+ middleware = [
69
+ SummarizationMiddleware(
70
+ model=self.model,
71
+ trigger=("tokens", int(context_cfg.get("summary_trigger_tokens", 12000))),
72
+ keep=("messages", int(context_cfg.get("keep_messages", 20))),
73
+ )
74
+ ]
75
+ return create_agent(
76
+ self.model,
77
+ tools=tools,
78
+ system_prompt=SYSTEM_PROMPT,
79
+ middleware=middleware,
80
+ checkpointer=self.memory.checkpointer,
81
+ store=self.memory.store,
82
+ name="prompt_copilot",
83
+ )
84
+
85
+ def _memory_context(self, user_text: str) -> str:
86
+ if not self.config.get("memory", {}).get("enabled", True):
87
+ return ""
88
+ namespace = ("memories", self.workspace_id)
89
+ limit = int(self.config.get("memory", {}).get("max_recent_memories", 5))
90
+ try:
91
+ items = self.memory.store.search(namespace, query=user_text, limit=max(1, limit))
92
+ except Exception:
93
+ items = self.memory.store.search(namespace, limit=max(1, limit))
94
+ if not items:
95
+ return ""
96
+ lines = ["Relevant durable project memory:"]
97
+ for item in items:
98
+ value = item.value
99
+ lines.append(f"- {value.get('content', value) if isinstance(value, dict) else value}")
100
+ return "\n".join(lines)
101
+
102
+ def invoke(self, user_text: str) -> str:
103
+ memory_context = self._memory_context(user_text)
104
+ content = user_text if not memory_context else f"{memory_context}\n\nCurrent request:\n{user_text}"
105
+ config = {
106
+ "configurable": {
107
+ "thread_id": self.thread_id,
108
+ "workspace_id": self.workspace_id,
109
+ }
110
+ }
111
+ result = self.agent.invoke({"messages": [{"role": "user", "content": content}]}, config)
112
+ messages = result.get("messages", [])
113
+ if not messages:
114
+ return ""
115
+ final = messages[-1]
116
+ value = getattr(final, "content", final.get("content", "") if isinstance(final, dict) else "")
117
+ if isinstance(value, list):
118
+ return "".join(str(part.get("text", part)) if isinstance(part, dict) else str(part) for part in value)
119
+ return str(value or "")
120
+
121
+ def reset(self) -> None:
122
+ self.memory.checkpointer.delete_thread(self.thread_id)
123
+ self.thread_id = str(uuid.uuid4())
124
+ (self.workspace.root / ".prompt-copilot-thread").write_text(self.thread_id, encoding="utf-8")
125
+
126
+ def close(self) -> None:
127
+ self.memory.close()