devduck 0.1.0__py3-none-any.whl → 0.1.1766644714__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.
Potentially problematic release.
This version of devduck might be problematic. Click here for more details.
- devduck/__init__.py +1439 -483
- devduck/__main__.py +7 -0
- devduck/_version.py +34 -0
- devduck/agentcore_handler.py +76 -0
- devduck/test_redduck.py +0 -1
- devduck/tools/__init__.py +47 -0
- devduck/tools/_ambient_input.py +423 -0
- devduck/tools/_tray_app.py +530 -0
- devduck/tools/agentcore_agents.py +197 -0
- devduck/tools/agentcore_config.py +441 -0
- devduck/tools/agentcore_invoke.py +423 -0
- devduck/tools/agentcore_logs.py +320 -0
- devduck/tools/ambient.py +157 -0
- devduck/tools/create_subagent.py +659 -0
- devduck/tools/fetch_github_tool.py +201 -0
- devduck/tools/install_tools.py +409 -0
- devduck/tools/ipc.py +546 -0
- devduck/tools/mcp_server.py +600 -0
- devduck/tools/scraper.py +935 -0
- devduck/tools/speech_to_speech.py +850 -0
- devduck/tools/state_manager.py +292 -0
- devduck/tools/store_in_kb.py +187 -0
- devduck/tools/system_prompt.py +608 -0
- devduck/tools/tcp.py +263 -94
- devduck/tools/tray.py +247 -0
- devduck/tools/use_github.py +438 -0
- devduck/tools/websocket.py +498 -0
- devduck-0.1.1766644714.dist-info/METADATA +717 -0
- devduck-0.1.1766644714.dist-info/RECORD +33 -0
- {devduck-0.1.0.dist-info → devduck-0.1.1766644714.dist-info}/entry_points.txt +1 -0
- devduck-0.1.1766644714.dist-info/licenses/LICENSE +201 -0
- devduck/install.sh +0 -42
- devduck-0.1.0.dist-info/METADATA +0 -106
- devduck-0.1.0.dist-info/RECORD +0 -11
- devduck-0.1.0.dist-info/licenses/LICENSE +0 -21
- {devduck-0.1.0.dist-info → devduck-0.1.1766644714.dist-info}/WHEEL +0 -0
- {devduck-0.1.0.dist-info → devduck-0.1.1766644714.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
"""System prompt management tool for Strands Agents.
|
|
2
|
+
|
|
3
|
+
This module provides a tool to view and modify system prompts used by the agent.
|
|
4
|
+
It helps with dynamic adaptation of the agent's behavior and capabilities,
|
|
5
|
+
and can persist changes by updating GitHub repository variables and local .prompt files.
|
|
6
|
+
|
|
7
|
+
Key Features:
|
|
8
|
+
1. View current system prompt from any environment variable
|
|
9
|
+
2. Update system prompt (in-memory, .prompt file, and GitHub repository variable)
|
|
10
|
+
3. Add context information to system prompt
|
|
11
|
+
4. Reset system prompt to default
|
|
12
|
+
5. Support for custom variable names (SYSTEM_PROMPT, TOOL_BUILDER_SYSTEM_PROMPT, etc.)
|
|
13
|
+
6. Local file persistence via .prompt files with predictable fallback locations
|
|
14
|
+
|
|
15
|
+
Usage Examples:
|
|
16
|
+
```python
|
|
17
|
+
from strands import Agent
|
|
18
|
+
from protocol_tools import system_prompt
|
|
19
|
+
|
|
20
|
+
agent = Agent(tools=[system_prompt])
|
|
21
|
+
|
|
22
|
+
# View current system prompt (default SYSTEM_PROMPT variable)
|
|
23
|
+
result = agent.tool.system_prompt(action="view")
|
|
24
|
+
|
|
25
|
+
# Update system prompt for tool builder
|
|
26
|
+
result = agent.tool.system_prompt(
|
|
27
|
+
action="update",
|
|
28
|
+
prompt="You are a specialized tool builder agent...",
|
|
29
|
+
repository="owner/repo",
|
|
30
|
+
variable_name="TOOL_BUILDER_SYSTEM_PROMPT",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Work with any custom variable name
|
|
34
|
+
result = agent.tool.system_prompt(
|
|
35
|
+
action="view", variable_name="MY_CUSTOM_PROMPT"
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
import os
|
|
41
|
+
import tempfile
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
from typing import Any
|
|
44
|
+
|
|
45
|
+
import requests
|
|
46
|
+
from strands import tool
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _get_github_token() -> str:
|
|
50
|
+
"""Get GitHub token from environment variable."""
|
|
51
|
+
return os.environ.get("PAT_TOKEN", os.environ.get("GITHUB_TOKEN", ""))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _get_prompt_file_path(variable_name: str = "SYSTEM_PROMPT") -> Path:
|
|
55
|
+
"""Get the path to the .prompt file for a given variable name with fallback strategy.
|
|
56
|
+
|
|
57
|
+
Tries locations in this order:
|
|
58
|
+
1. CWD (current working directory)
|
|
59
|
+
2. /tmp/devduck/prompts
|
|
60
|
+
3. tempdir/devduck/prompts
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
variable_name: Name of the variable (used to generate filename)
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Path to the .prompt file (first writable location)
|
|
67
|
+
"""
|
|
68
|
+
# Convert variable name to lowercase filename
|
|
69
|
+
# SYSTEM_PROMPT -> system_prompt.prompt
|
|
70
|
+
# MY_CUSTOM_PROMPT -> my_custom_prompt.prompt
|
|
71
|
+
filename = f"{variable_name.lower()}.prompt"
|
|
72
|
+
|
|
73
|
+
# Try 1: CWD
|
|
74
|
+
try:
|
|
75
|
+
cwd_path = Path.cwd() / filename
|
|
76
|
+
# Test if we can write to CWD
|
|
77
|
+
cwd_path.touch(exist_ok=True)
|
|
78
|
+
return cwd_path
|
|
79
|
+
except (OSError, PermissionError):
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
# Try 2: /tmp/devduck/prompts
|
|
83
|
+
try:
|
|
84
|
+
tmp_dir = Path("/tmp/devduck/prompts")
|
|
85
|
+
tmp_dir.mkdir(parents=True, exist_ok=True)
|
|
86
|
+
tmp_path = tmp_dir / filename
|
|
87
|
+
# Test if we can write to /tmp/devduck
|
|
88
|
+
tmp_path.touch(exist_ok=True)
|
|
89
|
+
return tmp_path
|
|
90
|
+
except (OSError, PermissionError):
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
# Try 3: tempdir/devduck/prompts (system temp directory)
|
|
94
|
+
temp_dir = Path(tempfile.gettempdir()) / "devduck" / "prompts"
|
|
95
|
+
temp_dir.mkdir(parents=True, exist_ok=True)
|
|
96
|
+
return temp_dir / filename
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _read_prompt_file(variable_name: str = "SYSTEM_PROMPT") -> str:
|
|
100
|
+
"""Read prompt from .prompt file across all possible locations.
|
|
101
|
+
|
|
102
|
+
Checks all locations in priority order and returns the first found.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
variable_name: Name of the variable
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Content of the .prompt file or empty string if not found
|
|
109
|
+
"""
|
|
110
|
+
filename = f"{variable_name.lower()}.prompt"
|
|
111
|
+
|
|
112
|
+
# Check all possible locations in priority order
|
|
113
|
+
possible_paths = [
|
|
114
|
+
Path.cwd() / filename, # CWD
|
|
115
|
+
Path("/tmp/devduck/prompts") / filename, # /tmp/devduck
|
|
116
|
+
Path(tempfile.gettempdir()) / "devduck" / "prompts" / filename, # tempdir
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
for prompt_file in possible_paths:
|
|
120
|
+
try:
|
|
121
|
+
if prompt_file.exists():
|
|
122
|
+
return prompt_file.read_text(encoding="utf-8")
|
|
123
|
+
except Exception:
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
return ""
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _write_prompt_file(
|
|
130
|
+
prompt: str, variable_name: str = "SYSTEM_PROMPT"
|
|
131
|
+
) -> tuple[bool, str]:
|
|
132
|
+
"""Write prompt to .prompt file with fallback strategy.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
prompt: The prompt content to write
|
|
136
|
+
variable_name: Name of the variable
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Tuple of (success, path) where success is True if write succeeded
|
|
140
|
+
"""
|
|
141
|
+
prompt_file = _get_prompt_file_path(variable_name)
|
|
142
|
+
try:
|
|
143
|
+
prompt_file.write_text(prompt, encoding="utf-8")
|
|
144
|
+
return True, str(prompt_file)
|
|
145
|
+
except Exception:
|
|
146
|
+
return False, str(prompt_file)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _delete_prompt_file(variable_name: str = "SYSTEM_PROMPT") -> tuple[bool, str]:
|
|
150
|
+
"""Delete .prompt file from all possible locations.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
variable_name: Name of the variable
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
Tuple of (success, path) - success if any file was deleted
|
|
157
|
+
"""
|
|
158
|
+
filename = f"{variable_name.lower()}.prompt"
|
|
159
|
+
deleted = False
|
|
160
|
+
deleted_path = ""
|
|
161
|
+
|
|
162
|
+
# Try to delete from all possible locations
|
|
163
|
+
possible_paths = [
|
|
164
|
+
Path.cwd() / filename, # CWD
|
|
165
|
+
Path("/tmp/devduck/prompts") / filename, # /tmp/devduck
|
|
166
|
+
Path(tempfile.gettempdir()) / "devduck" / "prompts" / filename, # tempdir
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
for prompt_file in possible_paths:
|
|
170
|
+
try:
|
|
171
|
+
if prompt_file.exists():
|
|
172
|
+
prompt_file.unlink()
|
|
173
|
+
deleted = True
|
|
174
|
+
deleted_path = str(prompt_file)
|
|
175
|
+
except Exception:
|
|
176
|
+
continue
|
|
177
|
+
|
|
178
|
+
return deleted, deleted_path
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _get_github_repository_variable(
|
|
182
|
+
repository: str, name: str, token: str
|
|
183
|
+
) -> dict[str, Any]:
|
|
184
|
+
"""Fetch a GitHub repository variable.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
repository: The repository in format "owner/repo"
|
|
188
|
+
name: The variable name
|
|
189
|
+
token: GitHub token
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Dictionary with success status, message, and value if successful
|
|
193
|
+
"""
|
|
194
|
+
# GitHub API endpoint for repository variables
|
|
195
|
+
url = f"https://api.github.com/repos/{repository}/actions/variables/{name}"
|
|
196
|
+
|
|
197
|
+
headers = {
|
|
198
|
+
"Accept": "application/vnd.github+json",
|
|
199
|
+
"Authorization": f"Bearer {token}",
|
|
200
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
try:
|
|
204
|
+
response = requests.get(url, headers=headers, timeout=30)
|
|
205
|
+
|
|
206
|
+
if response.status_code == 200:
|
|
207
|
+
data = response.json()
|
|
208
|
+
return {
|
|
209
|
+
"success": True,
|
|
210
|
+
"message": f"Variable {name} fetched successfully",
|
|
211
|
+
"value": data.get("value", ""),
|
|
212
|
+
}
|
|
213
|
+
else:
|
|
214
|
+
error_message = (
|
|
215
|
+
f"Failed to fetch variable: {response.status_code} - {response.text}"
|
|
216
|
+
)
|
|
217
|
+
return {"success": False, "message": error_message, "value": ""}
|
|
218
|
+
except Exception as e:
|
|
219
|
+
return {
|
|
220
|
+
"success": False,
|
|
221
|
+
"message": f"Error fetching GitHub variable: {e!s}",
|
|
222
|
+
"value": "",
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _get_system_prompt(
|
|
227
|
+
repository: str | None = None, variable_name: str = "SYSTEM_PROMPT"
|
|
228
|
+
) -> str:
|
|
229
|
+
"""Get the current system prompt.
|
|
230
|
+
|
|
231
|
+
Priority order:
|
|
232
|
+
1. Local environment variable
|
|
233
|
+
2. Local .prompt file (CWD → /tmp/devduck → tempdir)
|
|
234
|
+
3. GitHub repository variable (if repository specified)
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
repository: Optional GitHub repository in format "owner/repo"
|
|
238
|
+
variable_name: Name of the environment/repository variable to use
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
The system prompt string
|
|
242
|
+
"""
|
|
243
|
+
# First check local environment
|
|
244
|
+
local_prompt = os.environ.get(variable_name, "")
|
|
245
|
+
if local_prompt:
|
|
246
|
+
return local_prompt
|
|
247
|
+
|
|
248
|
+
# Second, check .prompt file across all locations
|
|
249
|
+
file_prompt = _read_prompt_file(variable_name)
|
|
250
|
+
if file_prompt:
|
|
251
|
+
# Load into environment for caching
|
|
252
|
+
os.environ[variable_name] = file_prompt
|
|
253
|
+
return file_prompt
|
|
254
|
+
|
|
255
|
+
# Third, if repository is provided, try GitHub
|
|
256
|
+
if repository:
|
|
257
|
+
token = _get_github_token()
|
|
258
|
+
if token:
|
|
259
|
+
result = _get_github_repository_variable(
|
|
260
|
+
repository=repository, name=variable_name, token=token
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
if result["success"] and result["value"]:
|
|
264
|
+
# Store in local environment and file for future use
|
|
265
|
+
os.environ[variable_name] = result["value"]
|
|
266
|
+
_write_prompt_file(result["value"], variable_name)
|
|
267
|
+
return str(result["value"])
|
|
268
|
+
|
|
269
|
+
# Default to empty string if nothing found
|
|
270
|
+
return ""
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _update_system_prompt(
|
|
274
|
+
new_prompt: str, variable_name: str = "SYSTEM_PROMPT"
|
|
275
|
+
) -> dict[str, Any]:
|
|
276
|
+
"""Update the system prompt in environment variable and .prompt file.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
new_prompt: The new prompt content
|
|
280
|
+
variable_name: Name of the variable
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Dictionary with success status and messages
|
|
284
|
+
"""
|
|
285
|
+
# Update environment variable
|
|
286
|
+
os.environ[variable_name] = new_prompt
|
|
287
|
+
|
|
288
|
+
# Update .prompt file with fallback strategy
|
|
289
|
+
file_success, file_path = _write_prompt_file(new_prompt, variable_name)
|
|
290
|
+
|
|
291
|
+
return {"env_updated": True, "file_updated": file_success, "file_path": file_path}
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _get_github_event_context() -> str:
|
|
295
|
+
"""Get GitHub event context information from environment variables."""
|
|
296
|
+
event_context = []
|
|
297
|
+
|
|
298
|
+
# GitHub repository information
|
|
299
|
+
repo = os.environ.get("GITHUB_REPOSITORY", "")
|
|
300
|
+
if repo:
|
|
301
|
+
event_context.append(f"Repository: {repo}")
|
|
302
|
+
|
|
303
|
+
# Event type
|
|
304
|
+
event_name = os.environ.get("GITHUB_EVENT_NAME", "")
|
|
305
|
+
if event_name:
|
|
306
|
+
event_context.append(f"Event Type: {event_name}")
|
|
307
|
+
|
|
308
|
+
# Actor
|
|
309
|
+
actor = os.environ.get("GITHUB_ACTOR", "")
|
|
310
|
+
if actor:
|
|
311
|
+
event_context.append(f"Actor: {actor}")
|
|
312
|
+
|
|
313
|
+
# Add more GitHub context variables as needed
|
|
314
|
+
return "\n".join(event_context)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _update_github_repository_variable(
|
|
318
|
+
repository: str, name: str, value: str, token: str
|
|
319
|
+
) -> dict[str, Any]:
|
|
320
|
+
"""Update a GitHub repository variable.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
repository: The repository in format "owner/repo"
|
|
324
|
+
name: The variable name
|
|
325
|
+
value: The variable value
|
|
326
|
+
token: GitHub token
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Dictionary with status and message
|
|
330
|
+
"""
|
|
331
|
+
# GitHub API endpoint for repository variables
|
|
332
|
+
url = f"https://api.github.com/repos/{repository}/actions/variables/{name}"
|
|
333
|
+
|
|
334
|
+
headers = {
|
|
335
|
+
"Accept": "application/vnd.github+json",
|
|
336
|
+
"Authorization": f"Bearer {token}",
|
|
337
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
data = {"name": name, "value": value}
|
|
341
|
+
|
|
342
|
+
response = requests.patch(url, headers=headers, json=data, timeout=30)
|
|
343
|
+
|
|
344
|
+
if response.status_code == 204:
|
|
345
|
+
return {"success": True, "message": f"Variable {name} updated successfully"}
|
|
346
|
+
else:
|
|
347
|
+
error_message = (
|
|
348
|
+
f"Failed to update variable: {response.status_code} - {response.text}"
|
|
349
|
+
)
|
|
350
|
+
return {"success": False, "message": error_message}
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
@tool
|
|
354
|
+
def system_prompt(
|
|
355
|
+
action: str,
|
|
356
|
+
prompt: str | None = None,
|
|
357
|
+
context: str | None = None,
|
|
358
|
+
repository: str | None = None,
|
|
359
|
+
variable_name: str = "SYSTEM_PROMPT",
|
|
360
|
+
) -> dict[str, str | list[dict[str, str]]]:
|
|
361
|
+
"""Manage the agent's system prompt.
|
|
362
|
+
|
|
363
|
+
This tool allows viewing and modifying the system prompt used by the agent.
|
|
364
|
+
It can be used to adapt the agent's behavior dynamically during runtime
|
|
365
|
+
and can update GitHub repository variables and local .prompt files to persist changes.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
action: The action to perform on the system prompt. One of:
|
|
369
|
+
- "view": View the current system prompt
|
|
370
|
+
- "update": Replace the current system prompt
|
|
371
|
+
- "add_context": Add additional context to the system prompt
|
|
372
|
+
- "reset": Reset to default (empty or environment-defined)
|
|
373
|
+
- "get_github_context": Get GitHub event context
|
|
374
|
+
prompt: New system prompt when using the "update" action
|
|
375
|
+
context: Additional context to add when using the "add_context" action
|
|
376
|
+
repository: GitHub repository in format "owner/repo" to update repository
|
|
377
|
+
variable (e.g., "cagataycali/report-agent")
|
|
378
|
+
variable_name: Name of the environment/repository variable to use
|
|
379
|
+
(default: "SYSTEM_PROMPT")
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
A dictionary with the operation status and current system prompt
|
|
383
|
+
|
|
384
|
+
Example:
|
|
385
|
+
```python
|
|
386
|
+
# View current system prompt
|
|
387
|
+
result = system_prompt(action="view")
|
|
388
|
+
|
|
389
|
+
# Update system prompt (saves to CWD → /tmp/devduck → tempdir)
|
|
390
|
+
result = system_prompt(
|
|
391
|
+
action="update", prompt="You are a specialized agent for task X..."
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
# Update GitHub repository variable (+ env var + .prompt file)
|
|
395
|
+
result = system_prompt(
|
|
396
|
+
action="update",
|
|
397
|
+
prompt="You are a specialized agent for task X...",
|
|
398
|
+
repository="owner/repo",
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
# Work with custom variable name
|
|
402
|
+
result = system_prompt(
|
|
403
|
+
action="update",
|
|
404
|
+
prompt="You are a tool builder...",
|
|
405
|
+
repository="owner/repo",
|
|
406
|
+
variable_name="TOOL_BUILDER_SYSTEM_PROMPT",
|
|
407
|
+
)
|
|
408
|
+
```
|
|
409
|
+
"""
|
|
410
|
+
try:
|
|
411
|
+
if action == "view":
|
|
412
|
+
current_prompt = _get_system_prompt(repository, variable_name)
|
|
413
|
+
|
|
414
|
+
# Determine source
|
|
415
|
+
source_parts = []
|
|
416
|
+
if os.environ.get(variable_name):
|
|
417
|
+
source_parts.append("environment variable")
|
|
418
|
+
|
|
419
|
+
# Check all possible file locations
|
|
420
|
+
filename = f"{variable_name.lower()}.prompt"
|
|
421
|
+
file_locations = [
|
|
422
|
+
(Path.cwd() / filename, "CWD"),
|
|
423
|
+
(Path("/tmp/devduck/prompts") / filename, "/tmp/devduck"),
|
|
424
|
+
(
|
|
425
|
+
Path(tempfile.gettempdir()) / "devduck" / "prompts" / filename,
|
|
426
|
+
"tempdir",
|
|
427
|
+
),
|
|
428
|
+
]
|
|
429
|
+
|
|
430
|
+
for file_path, location in file_locations:
|
|
431
|
+
if file_path.exists():
|
|
432
|
+
source_parts.append(f"file ({location}: {file_path})")
|
|
433
|
+
break
|
|
434
|
+
|
|
435
|
+
if repository:
|
|
436
|
+
source_parts.append(f"GitHub ({repository})")
|
|
437
|
+
|
|
438
|
+
source = " → ".join(source_parts) if source_parts else "not found"
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
"status": "success",
|
|
442
|
+
"content": [
|
|
443
|
+
{
|
|
444
|
+
"text": f"Current system prompt from {variable_name}:\nSource: {source}\n\n{current_prompt}"
|
|
445
|
+
}
|
|
446
|
+
],
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
elif action == "update":
|
|
450
|
+
if not prompt:
|
|
451
|
+
return {
|
|
452
|
+
"status": "error",
|
|
453
|
+
"content": [
|
|
454
|
+
{
|
|
455
|
+
"text": "Error: prompt parameter is required for the update action"
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
# Update in-memory environment variable and .prompt file
|
|
461
|
+
update_result = _update_system_prompt(prompt, variable_name)
|
|
462
|
+
|
|
463
|
+
messages = []
|
|
464
|
+
messages.append(f"✓ Environment variable updated ({variable_name})")
|
|
465
|
+
|
|
466
|
+
if update_result["file_updated"]:
|
|
467
|
+
messages.append(f"✓ File saved ({update_result['file_path']})")
|
|
468
|
+
else:
|
|
469
|
+
messages.append(f"⚠ File save failed ({update_result['file_path']})")
|
|
470
|
+
|
|
471
|
+
# If repository is specified, also update GitHub repository variable
|
|
472
|
+
if repository:
|
|
473
|
+
token = _get_github_token()
|
|
474
|
+
if not token:
|
|
475
|
+
messages.append(
|
|
476
|
+
"⚠ GitHub token not available - skipped repository update"
|
|
477
|
+
)
|
|
478
|
+
else:
|
|
479
|
+
result = _update_github_repository_variable(
|
|
480
|
+
repository=repository,
|
|
481
|
+
name=variable_name,
|
|
482
|
+
value=prompt,
|
|
483
|
+
token=token,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
if result["success"]:
|
|
487
|
+
messages.append(
|
|
488
|
+
f"✓ GitHub repository variable updated ({repository})"
|
|
489
|
+
)
|
|
490
|
+
else:
|
|
491
|
+
messages.append(f"⚠ GitHub update failed: {result['message']}")
|
|
492
|
+
|
|
493
|
+
return {
|
|
494
|
+
"status": "success",
|
|
495
|
+
"content": [{"text": "\n".join(messages)}],
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
elif action == "add_context":
|
|
499
|
+
if not context:
|
|
500
|
+
return {
|
|
501
|
+
"status": "error",
|
|
502
|
+
"content": [
|
|
503
|
+
{
|
|
504
|
+
"text": "Error: context parameter is required for the add_context action"
|
|
505
|
+
}
|
|
506
|
+
],
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
current_prompt = _get_system_prompt(repository, variable_name)
|
|
510
|
+
new_prompt = f"{current_prompt}\n\n{context}" if current_prompt else context
|
|
511
|
+
|
|
512
|
+
# Update in-memory environment variable and .prompt file
|
|
513
|
+
update_result = _update_system_prompt(new_prompt, variable_name)
|
|
514
|
+
|
|
515
|
+
messages = []
|
|
516
|
+
messages.append(f"✓ Context added to {variable_name}")
|
|
517
|
+
messages.append(f"✓ Environment variable updated")
|
|
518
|
+
|
|
519
|
+
if update_result["file_updated"]:
|
|
520
|
+
messages.append(f"✓ File saved ({update_result['file_path']})")
|
|
521
|
+
else:
|
|
522
|
+
messages.append(f"⚠ File save failed ({update_result['file_path']})")
|
|
523
|
+
|
|
524
|
+
# If repository is specified, also update GitHub repository variable
|
|
525
|
+
if repository:
|
|
526
|
+
token = _get_github_token()
|
|
527
|
+
if not token:
|
|
528
|
+
messages.append(
|
|
529
|
+
"⚠ GitHub token not available - skipped repository update"
|
|
530
|
+
)
|
|
531
|
+
else:
|
|
532
|
+
result = _update_github_repository_variable(
|
|
533
|
+
repository=repository,
|
|
534
|
+
name=variable_name,
|
|
535
|
+
value=new_prompt,
|
|
536
|
+
token=token,
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
if result["success"]:
|
|
540
|
+
messages.append(
|
|
541
|
+
f"✓ GitHub repository variable updated ({repository})"
|
|
542
|
+
)
|
|
543
|
+
else:
|
|
544
|
+
messages.append(f"⚠ GitHub update failed: {result['message']}")
|
|
545
|
+
|
|
546
|
+
return {
|
|
547
|
+
"status": "success",
|
|
548
|
+
"content": [{"text": "\n".join(messages)}],
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
elif action == "reset":
|
|
552
|
+
# Reset environment variable
|
|
553
|
+
os.environ.pop(variable_name, None)
|
|
554
|
+
|
|
555
|
+
# Delete .prompt file from all locations
|
|
556
|
+
file_deleted, deleted_path = _delete_prompt_file(variable_name)
|
|
557
|
+
|
|
558
|
+
messages = []
|
|
559
|
+
messages.append(f"✓ Environment variable reset ({variable_name})")
|
|
560
|
+
|
|
561
|
+
if file_deleted:
|
|
562
|
+
messages.append(f"✓ File deleted ({deleted_path})")
|
|
563
|
+
else:
|
|
564
|
+
messages.append("⚠ File deletion failed or file doesn't exist")
|
|
565
|
+
|
|
566
|
+
# If repository is specified, reset GitHub repository variable
|
|
567
|
+
if repository:
|
|
568
|
+
token = _get_github_token()
|
|
569
|
+
if not token:
|
|
570
|
+
messages.append(
|
|
571
|
+
"⚠ GitHub token not available - skipped repository reset"
|
|
572
|
+
)
|
|
573
|
+
else:
|
|
574
|
+
result = _update_github_repository_variable(
|
|
575
|
+
repository=repository, name=variable_name, value="", token=token
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
if result["success"]:
|
|
579
|
+
messages.append(
|
|
580
|
+
f"✓ GitHub repository variable reset ({repository})"
|
|
581
|
+
)
|
|
582
|
+
else:
|
|
583
|
+
messages.append(f"⚠ GitHub reset failed: {result['message']}")
|
|
584
|
+
|
|
585
|
+
return {
|
|
586
|
+
"status": "success",
|
|
587
|
+
"content": [{"text": "\n".join(messages)}],
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
elif action == "get_github_context":
|
|
591
|
+
github_context = _get_github_event_context()
|
|
592
|
+
return {
|
|
593
|
+
"status": "success",
|
|
594
|
+
"content": [{"text": f"GitHub Event Context:\n\n{github_context}"}],
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
else:
|
|
598
|
+
return {
|
|
599
|
+
"status": "error",
|
|
600
|
+
"content": [
|
|
601
|
+
{
|
|
602
|
+
"text": f"Error: Unknown action '{action}'. Valid actions are view, update, add_context, reset, get_github_context"
|
|
603
|
+
}
|
|
604
|
+
],
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
except Exception as e:
|
|
608
|
+
return {"status": "error", "content": [{"text": f"Error: {e!s}"}]}
|