devduck 1.1.0__py3-none-any.whl → 1.1.4__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.

@@ -2,14 +2,15 @@
2
2
 
3
3
  This module provides a tool to view and modify system prompts used by the agent.
4
4
  It helps with dynamic adaptation of the agent's behavior and capabilities,
5
- and can persist changes by updating GitHub repository variables.
5
+ and can persist changes by updating GitHub repository variables and local .prompt files.
6
6
 
7
7
  Key Features:
8
8
  1. View current system prompt from any environment variable
9
- 2. Update system prompt (in-memory and GitHub repository variable)
9
+ 2. Update system prompt (in-memory, .prompt file, and GitHub repository variable)
10
10
  3. Add context information to system prompt
11
11
  4. Reset system prompt to default
12
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
13
14
 
14
15
  Usage Examples:
15
16
  ```python
@@ -37,6 +38,8 @@ result = agent.tool.system_prompt(
37
38
  """
38
39
 
39
40
  import os
41
+ import tempfile
42
+ from pathlib import Path
40
43
  from typing import Any
41
44
 
42
45
  import requests
@@ -48,6 +51,133 @@ def _get_github_token() -> str:
48
51
  return os.environ.get("PAT_TOKEN", os.environ.get("GITHUB_TOKEN", ""))
49
52
 
50
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
+
51
181
  def _get_github_repository_variable(
52
182
  repository: str, name: str, token: str
53
183
  ) -> dict[str, Any]:
@@ -98,8 +228,10 @@ def _get_system_prompt(
98
228
  ) -> str:
99
229
  """Get the current system prompt.
100
230
 
101
- First checks the local environment variable.
102
- If empty and repository is provided, tries to fetch from GitHub repository variables.
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)
103
235
 
104
236
  Args:
105
237
  repository: Optional GitHub repository in format "owner/repo"
@@ -113,18 +245,25 @@ def _get_system_prompt(
113
245
  if local_prompt:
114
246
  return local_prompt
115
247
 
116
- # If local is empty and repository is provided, try GitHub
117
- if repository and not local_prompt:
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:
118
257
  token = _get_github_token()
119
258
  if token:
120
259
  result = _get_github_repository_variable(
121
260
  repository=repository, name=variable_name, token=token
122
261
  )
123
262
 
124
- if result["success"]:
125
- # Store in local environment for future use
126
- if result["value"]:
127
- os.environ[variable_name] = result["value"]
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)
128
267
  return str(result["value"])
129
268
 
130
269
  # Default to empty string if nothing found
@@ -133,10 +272,24 @@ def _get_system_prompt(
133
272
 
134
273
  def _update_system_prompt(
135
274
  new_prompt: str, variable_name: str = "SYSTEM_PROMPT"
136
- ) -> None:
137
- """Update the system prompt in the environment variable."""
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
138
286
  os.environ[variable_name] = new_prompt
139
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
+
140
293
 
141
294
  def _get_github_event_context() -> str:
142
295
  """Get GitHub event context information from environment variables."""
@@ -209,7 +362,7 @@ def system_prompt(
209
362
 
210
363
  This tool allows viewing and modifying the system prompt used by the agent.
211
364
  It can be used to adapt the agent's behavior dynamically during runtime
212
- and can update GitHub repository variables to persist changes.
365
+ and can update GitHub repository variables and local .prompt files to persist changes.
213
366
 
214
367
  Args:
215
368
  action: The action to perform on the system prompt. One of:
@@ -233,12 +386,12 @@ def system_prompt(
233
386
  # View current system prompt
234
387
  result = system_prompt(action="view")
235
388
 
236
- # Update system prompt in memory
389
+ # Update system prompt (saves to CWD → /tmp/devduck → tempdir)
237
390
  result = system_prompt(
238
391
  action="update", prompt="You are a specialized agent for task X..."
239
392
  )
240
393
 
241
- # Update GitHub repository variable
394
+ # Update GitHub repository variable (+ env var + .prompt file)
242
395
  result = system_prompt(
243
396
  action="update",
244
397
  prompt="You are a specialized agent for task X...",
@@ -257,16 +410,38 @@ def system_prompt(
257
410
  try:
258
411
  if action == "view":
259
412
  current_prompt = _get_system_prompt(repository, variable_name)
260
- source = "local environment"
261
413
 
262
- if not os.environ.get(variable_name) and repository:
263
- source = f"GitHub repository {repository}"
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"
264
439
 
265
440
  return {
266
441
  "status": "success",
267
442
  "content": [
268
443
  {
269
- "text": f"Current system prompt from {variable_name} (from {source}):\n\n{current_prompt}"
444
+ "text": f"Current system prompt from {variable_name}:\nSource: {source}\n\n{current_prompt}"
270
445
  }
271
446
  ],
272
447
  }
@@ -282,58 +457,42 @@ def system_prompt(
282
457
  ],
283
458
  }
284
459
 
285
- # Update in-memory environment variable
286
- _update_system_prompt(prompt, variable_name)
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']})")
287
470
 
288
471
  # If repository is specified, also update GitHub repository variable
289
472
  if repository:
290
473
  token = _get_github_token()
291
474
  if not token:
292
- return {
293
- "status": "error",
294
- "content": [
295
- {
296
- "text": "Error: GitHub token not available. Cannot update repository variable."
297
- }
298
- ],
299
- }
300
-
301
- result = _update_github_repository_variable(
302
- repository=repository, name=variable_name, value=prompt, token=token
303
- )
304
-
305
- if result["success"]:
306
- return {
307
- "status": "success",
308
- "content": [
309
- {
310
- "text": f"System prompt updated successfully in memory ({variable_name})"
311
- },
312
- {
313
- "text": f"GitHub repository variable updated: {result['message']}"
314
- },
315
- ],
316
- }
475
+ messages.append(
476
+ " GitHub token not available - skipped repository update"
477
+ )
317
478
  else:
318
- return {
319
- "status": "error",
320
- "content": [
321
- {
322
- "text": f"System prompt updated successfully in memory ({variable_name})"
323
- },
324
- {
325
- "text": f"GitHub repository variable update failed: {result['message']}"
326
- },
327
- ],
328
- }
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']}")
329
492
 
330
493
  return {
331
494
  "status": "success",
332
- "content": [
333
- {
334
- "text": f"System prompt updated successfully in memory ({variable_name})"
335
- }
336
- ],
495
+ "content": [{"text": "\n".join(messages)}],
337
496
  }
338
497
 
339
498
  elif action == "add_context":
@@ -349,119 +508,83 @@ def system_prompt(
349
508
 
350
509
  current_prompt = _get_system_prompt(repository, variable_name)
351
510
  new_prompt = f"{current_prompt}\n\n{context}" if current_prompt else context
352
- _update_system_prompt(new_prompt, variable_name)
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']})")
353
523
 
354
524
  # If repository is specified, also update GitHub repository variable
355
525
  if repository:
356
526
  token = _get_github_token()
357
527
  if not token:
358
- return {
359
- "status": "error",
360
- "content": [
361
- {
362
- "text": f"Context added to system prompt successfully in memory ({variable_name})"
363
- },
364
- {
365
- "text": "Error: GitHub token not available. Cannot update repository variable."
366
- },
367
- ],
368
- }
369
-
370
- result = _update_github_repository_variable(
371
- repository=repository,
372
- name=variable_name,
373
- value=new_prompt,
374
- token=token,
375
- )
376
-
377
- if result["success"]:
378
- return {
379
- "status": "success",
380
- "content": [
381
- {
382
- "text": f"Context added to system prompt successfully in memory ({variable_name})"
383
- },
384
- {
385
- "text": f"GitHub repository variable updated: {result['message']}"
386
- },
387
- ],
388
- }
528
+ messages.append(
529
+ " GitHub token not available - skipped repository update"
530
+ )
389
531
  else:
390
- return {
391
- "status": "error",
392
- "content": [
393
- {
394
- "text": f"Context added to system prompt successfully in memory ({variable_name})"
395
- },
396
- {
397
- "text": f"GitHub repository variable update failed: {result['message']}"
398
- },
399
- ],
400
- }
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']}")
401
545
 
402
546
  return {
403
547
  "status": "success",
404
- "content": [
405
- {
406
- "text": f"Context added to system prompt successfully ({variable_name})"
407
- }
408
- ],
548
+ "content": [{"text": "\n".join(messages)}],
409
549
  }
410
550
 
411
551
  elif action == "reset":
412
- # Reset to empty or environment-defined default
552
+ # Reset environment variable
413
553
  os.environ.pop(variable_name, None)
414
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
+
415
566
  # If repository is specified, reset GitHub repository variable
416
567
  if repository:
417
568
  token = _get_github_token()
418
569
  if not token:
419
- return {
420
- "status": "error",
421
- "content": [
422
- {
423
- "text": f"System prompt reset to default in memory ({variable_name})"
424
- },
425
- {
426
- "text": "Error: GitHub token not available. Cannot update repository variable."
427
- },
428
- ],
429
- }
430
-
431
- result = _update_github_repository_variable(
432
- repository=repository, name=variable_name, value="", token=token
433
- )
434
-
435
- if result["success"]:
436
- return {
437
- "status": "success",
438
- "content": [
439
- {
440
- "text": f"System prompt reset to default in memory ({variable_name})"
441
- },
442
- {
443
- "text": f"GitHub repository variable reset: {result['message']}"
444
- },
445
- ],
446
- }
570
+ messages.append(
571
+ " GitHub token not available - skipped repository reset"
572
+ )
447
573
  else:
448
- return {
449
- "status": "error",
450
- "content": [
451
- {
452
- "text": f"System prompt reset to default in memory ({variable_name})"
453
- },
454
- {
455
- "text": f"GitHub repository variable reset failed: {result['message']}"
456
- },
457
- ],
458
- }
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']}")
459
584
 
460
585
  return {
461
586
  "status": "success",
462
- "content": [
463
- {"text": f"System prompt reset to default ({variable_name})"}
464
- ],
587
+ "content": [{"text": "\n".join(messages)}],
465
588
  }
466
589
 
467
590
  elif action == "get_github_context":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devduck
3
- Version: 1.1.0
3
+ Version: 1.1.4
4
4
  Summary: 🦆 Extreme minimalist self-adapting AI agent - one file, self-healing, runtime dependencies
5
5
  Author-email: Cagatay Cali <cagataycali@icloud.com>
6
6
  License: Apache-2.0
@@ -40,6 +40,7 @@ Requires-Dist: beautifulsoup4
40
40
  Requires-Dist: colorama
41
41
  Requires-Dist: websockets
42
42
  Requires-Dist: strands-mcp-server
43
+ Requires-Dist: strands-google
43
44
  Requires-Dist: bedrock-agentcore-starter-toolkit
44
45
  Requires-Dist: bedrock-agentcore
45
46
  Requires-Dist: rumps; sys_platform == "darwin"
@@ -1,9 +1,9 @@
1
- devduck/__init__.py,sha256=P7xQxthfPj2sDfcxn-kwA24gtBbtfDYu2Tf_y8KuEic,71545
1
+ devduck/__init__.py,sha256=CVG9qHRG-63ZNI6nLGFyAqvv4m9mgSB46s5XAVM9HOM,75958
2
2
  devduck/__main__.py,sha256=aeF2RR4k7lzSR2X1QKV9XQPCKhtsH0JYUv2etBBqmL0,145
3
- devduck/_version.py,sha256=ePNVzJOkxR8FY5bezqKQ_fgBRbzH1G7QTaRDHvGQRAY,704
3
+ devduck/_version.py,sha256=u-IJdVvNgkPmB4EypXx7iHPUTbdrT6j_v7FWXSVMszE,704
4
4
  devduck/agentcore_handler.py,sha256=0DKJTTjoH9P8a70G0f5dOIIwy6bjqaN46voAWaSOpDY,2221
5
5
  devduck/test_redduck.py,sha256=ILtKKMuoyVfmhnibmbojpbOsqbcKooZv4j9qtE2LWdw,1750
6
- devduck/tools/__init__.py,sha256=AmIy8MInaClaZ71fqzy4EQJnBWsLkrv4QW9IIN7UQyw,1367
6
+ devduck/tools/__init__.py,sha256=GtqhtyTeWz3Glwj7MJ1ncKIQf_0KFu33AmtBOeIm3XY,1176
7
7
  devduck/tools/_ambient_input.py,sha256=3lBgLO81BvkxjgTrQc-EuxNLXmO1oPUt2Ysg1jR4Fsk,13897
8
8
  devduck/tools/_tray_app.py,sha256=E4rtJcegRsBs_FdQVGdA-0Ax7uxVb6AbuyqjwCArHj0,19405
9
9
  devduck/tools/agentcore_agents.py,sha256=fiDNhl7R2tVbp1mEOySJTfGXwap5q3COenYOjiJDE_g,6488
@@ -12,20 +12,22 @@ devduck/tools/agentcore_invoke.py,sha256=iHOeV8mh1QeJ_dj06MRHbJ1VnvY4WIQxqruxIDw
12
12
  devduck/tools/agentcore_logs.py,sha256=A3YQIoRErJtvzeaMSPNqOLX1BH-vYTbYKs1NXoCnC5E,10222
13
13
  devduck/tools/ambient.py,sha256=HB1ZhfeOdOaMU0xe4e44VNUT_-DQ5SY7sl3r4r-4X44,4806
14
14
  devduck/tools/create_subagent.py,sha256=UzRz9BmU4PbTveZROEpZ311aH-u-i6x89gttu-CniAE,24687
15
+ devduck/tools/fetch_github_tool.py,sha256=V9mZ7jNHARK7wC3XvLyzmJk0FzRCwQwNgx7PrwoY2uc,6871
15
16
  devduck/tools/install_tools.py,sha256=3uzRg5lEHX-L6gxnFn3mIKjGYDJ3h_AdwGnEwKA9qR0,14284
16
17
  devduck/tools/ipc.py,sha256=e3KJeR2HmCKEtVLGNOtf6CeFi3pTDehwd7Fu4JJ19Ms,18607
17
18
  devduck/tools/mcp_server.py,sha256=Ybp0PcJKW2TOvghsRL-i8Guqc9WokPwOD2bhVgzoj6Q,21490
18
- devduck/tools/speech_to_speech.py,sha256=rw9Olrdd_JvfeInk1ZeztVzSSuw5QQ_2Vnt-WbtLu50,28627
19
+ devduck/tools/scraper.py,sha256=OaENn8vEzVmvmlLBERDleIU-v2SlQ5k2SaLPmkQq1uY,38877
20
+ devduck/tools/speech_to_speech.py,sha256=sA-EySl4W00OOhhPl6UmDBQY0ptL3oArjeGq2xRMbNU,32728
19
21
  devduck/tools/state_manager.py,sha256=hrleqdVoCboNd8R3wDRUXVKYCZdGoe1j925i948LTHc,10563
20
22
  devduck/tools/store_in_kb.py,sha256=-JM-oRQKR3FBubKHFHmXRnZSvi9dVgHxG0lismMgG2k,6861
21
- devduck/tools/system_prompt.py,sha256=waAdmvRhyulorw_tLqpqUJN_AahuaeF2rXqjMqN7IRY,16905
23
+ devduck/tools/system_prompt.py,sha256=k5iLDjQRKeGEIa9G4cpNrfzDF4tOiqnJGqDVMkVlfko,20548
22
24
  devduck/tools/tcp.py,sha256=w2m_Jf6vZ4NYu0AwgZd7C7eKs4No2EVHZ2WYIl_Bt0A,22017
23
25
  devduck/tools/tray.py,sha256=FgVhUtLdsdv5_ERK-RyAIpDE8Zb0IfoqhHQdwMxrHUQ,7547
24
26
  devduck/tools/use_github.py,sha256=nr3JSGk48mKUobpgW__2gu6lFyUj93a1XRs3I6vH8W4,13682
25
27
  devduck/tools/websocket.py,sha256=A8bqgdDZs8hcf2HctkJzQOzMvb5mXUC7YZ-xqkOyn94,16959
26
- devduck-1.1.0.dist-info/licenses/LICENSE,sha256=UANcoWwfVeuM9597WUkjEQbzqIUH0bJoE9Tpwgj_LvU,11345
27
- devduck-1.1.0.dist-info/METADATA,sha256=UM7NICyyRNPlMkvh-qKaGktgJGjxEi6qboUeIzLmwvo,21855
28
- devduck-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
- devduck-1.1.0.dist-info/entry_points.txt,sha256=PJ8gvdi2MnKEK8yCwcmZDeLQ-lx94EV_jp4-v8AKuTA,58
30
- devduck-1.1.0.dist-info/top_level.txt,sha256=ySXWlVronp8xHYfQ_Hdfr463e0EnbWuqyuxs94EU7yk,8
31
- devduck-1.1.0.dist-info/RECORD,,
28
+ devduck-1.1.4.dist-info/licenses/LICENSE,sha256=UANcoWwfVeuM9597WUkjEQbzqIUH0bJoE9Tpwgj_LvU,11345
29
+ devduck-1.1.4.dist-info/METADATA,sha256=xnf0MtlwifjEpTP9Ghcy5Xsx6uTJzX52sDsso8UvsNw,21885
30
+ devduck-1.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ devduck-1.1.4.dist-info/entry_points.txt,sha256=PJ8gvdi2MnKEK8yCwcmZDeLQ-lx94EV_jp4-v8AKuTA,58
32
+ devduck-1.1.4.dist-info/top_level.txt,sha256=ySXWlVronp8xHYfQ_Hdfr463e0EnbWuqyuxs94EU7yk,8
33
+ devduck-1.1.4.dist-info/RECORD,,