npcsh 1.1.9__py3-none-any.whl → 1.1.11__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.
Files changed (82) hide show
  1. npcsh/_state.py +45 -12
  2. npcsh/guac.py +6 -4
  3. npcsh/npc_team/jinxs/code/sh.jinx +32 -13
  4. npcsh/npc_team/jinxs/code/sql.jinx +2 -2
  5. npcsh/npc_team/jinxs/utils/agent.jinx +17 -0
  6. npcsh/npc_team/jinxs/utils/chat.jinx +17 -0
  7. npcsh/npc_team/jinxs/utils/compress.jinx +140 -0
  8. npcsh/npc_team/jinxs/utils/load_file.jinx +35 -0
  9. npcsh/npc_team/jinxs/utils/serve.jinx +0 -3
  10. npcsh/npc_team/jinxs/utils/trigger.jinx +39 -14
  11. npcsh/npc_team/jinxs/utils/vixynt.jinx +104 -77
  12. npcsh/npcsh.py +2 -1
  13. npcsh/routes.py +0 -1
  14. npcsh-1.1.11.data/data/npcsh/npc_team/agent.jinx +17 -0
  15. npcsh-1.1.11.data/data/npcsh/npc_team/chat.jinx +17 -0
  16. npcsh-1.1.11.data/data/npcsh/npc_team/compress.jinx +140 -0
  17. npcsh-1.1.11.data/data/npcsh/npc_team/load_file.jinx +35 -0
  18. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/serve.jinx +0 -3
  19. npcsh-1.1.11.data/data/npcsh/npc_team/sh.jinx +38 -0
  20. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/sql.jinx +2 -2
  21. npcsh-1.1.11.data/data/npcsh/npc_team/trigger.jinx +61 -0
  22. npcsh-1.1.11.data/data/npcsh/npc_team/vixynt.jinx +144 -0
  23. {npcsh-1.1.9.dist-info → npcsh-1.1.11.dist-info}/METADATA +1 -1
  24. npcsh-1.1.11.dist-info/RECORD +126 -0
  25. npcsh/npc_team/jinxs/utils/breathe.jinx +0 -20
  26. npcsh/npc_team/jinxs/utils/flush.jinx +0 -39
  27. npcsh/npc_team/jinxs/utils/plan.jinx +0 -33
  28. npcsh-1.1.9.data/data/npcsh/npc_team/breathe.jinx +0 -20
  29. npcsh-1.1.9.data/data/npcsh/npc_team/flush.jinx +0 -39
  30. npcsh-1.1.9.data/data/npcsh/npc_team/plan.jinx +0 -33
  31. npcsh-1.1.9.data/data/npcsh/npc_team/sh.jinx +0 -19
  32. npcsh-1.1.9.data/data/npcsh/npc_team/trigger.jinx +0 -36
  33. npcsh-1.1.9.data/data/npcsh/npc_team/vixynt.jinx +0 -117
  34. npcsh-1.1.9.dist-info/RECORD +0 -124
  35. /npcsh/npc_team/jinxs/{utils → npc_studio}/npc-studio.jinx +0 -0
  36. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/alicanto.jinx +0 -0
  37. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/alicanto.npc +0 -0
  38. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/alicanto.png +0 -0
  39. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/build.jinx +0 -0
  40. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/compile.jinx +0 -0
  41. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/corca.jinx +0 -0
  42. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/corca.npc +0 -0
  43. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/corca.png +0 -0
  44. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/corca_example.png +0 -0
  45. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/edit_file.jinx +0 -0
  46. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/foreman.npc +0 -0
  47. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/frederic.npc +0 -0
  48. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/frederic4.png +0 -0
  49. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/guac.jinx +0 -0
  50. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/guac.png +0 -0
  51. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/help.jinx +0 -0
  52. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/init.jinx +0 -0
  53. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/jinxs.jinx +0 -0
  54. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/kadiefa.npc +0 -0
  55. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/kadiefa.png +0 -0
  56. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/npc-studio.jinx +0 -0
  57. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/npcsh.ctx +0 -0
  58. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
  59. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/ots.jinx +0 -0
  60. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/plonk.jinx +0 -0
  61. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/plonk.npc +0 -0
  62. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/plonk.png +0 -0
  63. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/plonkjr.npc +0 -0
  64. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/plonkjr.png +0 -0
  65. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/pti.jinx +0 -0
  66. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/python.jinx +0 -0
  67. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/roll.jinx +0 -0
  68. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/sample.jinx +0 -0
  69. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/search.jinx +0 -0
  70. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/set.jinx +0 -0
  71. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/sibiji.npc +0 -0
  72. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/sibiji.png +0 -0
  73. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/sleep.jinx +0 -0
  74. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/spool.jinx +0 -0
  75. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/spool.png +0 -0
  76. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/wander.jinx +0 -0
  77. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/yap.jinx +0 -0
  78. {npcsh-1.1.9.data → npcsh-1.1.11.data}/data/npcsh/npc_team/yap.png +0 -0
  79. {npcsh-1.1.9.dist-info → npcsh-1.1.11.dist-info}/WHEEL +0 -0
  80. {npcsh-1.1.9.dist-info → npcsh-1.1.11.dist-info}/entry_points.txt +0 -0
  81. {npcsh-1.1.9.dist-info → npcsh-1.1.11.dist-info}/licenses/LICENSE +0 -0
  82. {npcsh-1.1.9.dist-info → npcsh-1.1.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,144 @@
1
+ jinx_name: "vixynt"
2
+ description: "Generates images from text descriptions or edits existing ones."
3
+ inputs:
4
+ - prompt
5
+ - model: null
6
+ - provider: null
7
+ - output_name: null
8
+ - attachments: null
9
+ - n_images: null
10
+ - height: null
11
+ - width: null
12
+ steps:
13
+ - name: "generate_or_edit_image"
14
+ engine: "python"
15
+ code: |
16
+ import os
17
+ import base64
18
+ from io import BytesIO
19
+ from datetime import datetime
20
+ from PIL import Image
21
+ from npcpy.llm_funcs import gen_image
22
+
23
+ # Extract inputs from context with proper type conversion
24
+ image_prompt = str(context.get('prompt', '')).strip()
25
+ output_name = context.get('output_name')
26
+ attachments_str = context.get('attachments')
27
+
28
+ # Handle integer inputs - they may come as strings or ints
29
+ try:
30
+ n_images = int(context.get('n_images', 1))
31
+ except (ValueError, TypeError):
32
+ n_images = 1
33
+
34
+ try:
35
+ height = int(context.get('height', 1024))
36
+ except (ValueError, TypeError):
37
+ height = 1024
38
+
39
+ try:
40
+ width = int(context.get('width', 1024))
41
+ except (ValueError, TypeError):
42
+ width = 1024
43
+
44
+ # Get model and provider, prioritizing context, then NPC, then environment variables
45
+ model = context.get('model')
46
+ provider = context.get('provider')
47
+
48
+ # Use NPC's model/provider as fallback
49
+ if not model and npc and hasattr(npc, 'model') and npc.model:
50
+ model = npc.model
51
+ if not provider and npc and hasattr(npc, 'provider') and npc.provider:
52
+ provider = npc.provider
53
+
54
+ # Fallback to environment variables
55
+ if not model:
56
+ model = os.getenv('NPCSH_IMAGE_GEN_MODEL')
57
+ if not provider:
58
+ provider = os.getenv('NPCSH_IMAGE_GEN_PROVIDER')
59
+
60
+ # Final hardcoded fallbacks if nothing else is set
61
+ if not model:
62
+ model = "runwayml/stable-diffusion-v1-5"
63
+ if not provider:
64
+ provider = "diffusers"
65
+
66
+ # Parse attachments
67
+ input_images = []
68
+ if attachments_str and str(attachments_str).strip():
69
+ input_images = [p.strip() for p in str(attachments_str).split(',')]
70
+
71
+ output_messages = context.get('messages', [])
72
+
73
+ if not image_prompt:
74
+ output = "Error: No prompt provided for image generation."
75
+ else:
76
+ try:
77
+ # Generate image(s)
78
+ result = gen_image(
79
+ prompt=image_prompt,
80
+ model=model,
81
+ provider=provider,
82
+ npc=npc,
83
+ height=height,
84
+ width=width,
85
+ n_images=n_images,
86
+ input_images=input_images if input_images else None
87
+ )
88
+
89
+ # Ensure we have a list of images
90
+ if not isinstance(result, list):
91
+ images_list = [result] if result is not None else []
92
+ else:
93
+ images_list = result
94
+
95
+ saved_files = []
96
+ html_image_tags = [] # This list will store the raw HTML <img> tags
97
+
98
+ for i, image in enumerate(images_list):
99
+ if image is None:
100
+ continue
101
+
102
+ # Determine output filename
103
+ if output_name and str(output_name).strip():
104
+ base_name, ext = os.path.splitext(os.path.expanduser(str(output_name)))
105
+ if not ext:
106
+ ext = ".png"
107
+ current_output_file = f"{base_name}_{i}{ext}" if len(images_list) > 1 else f"{base_name}{ext}"
108
+ else:
109
+ os.makedirs(os.path.expanduser("~/.npcsh/images/"), exist_ok=True)
110
+ current_output_file = (
111
+ os.path.expanduser("~/.npcsh/images/")
112
+ + f"image_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{i}.png"
113
+ )
114
+
115
+ # Save image to file
116
+ image.save(current_output_file)
117
+ saved_files.append(current_output_file)
118
+
119
+ # Convert image to base64 and create an HTML <img> tag
120
+ with open(current_output_file, 'rb') as f:
121
+ img_data = base64.b64encode(f.read()).decode()
122
+ # Using raw HTML <img> tag with data URI
123
+ html_image_tags.append(f'<img src="data:image/png;base64,{img_data}" alt="Generated Image {i+1}" style="max-width: 100%; display: block; margin-top: 10px;">')
124
+
125
+ if saved_files:
126
+ output_text_message = f"Image(s) generated and saved to: {', '.join(saved_files)}"
127
+ if input_images:
128
+ output_text_message = f"Image(s) edited and saved to: {', '.join(saved_files)}"
129
+
130
+ output = output_text_message # Keep the text message clean
131
+ output += f"\n\nThe image files have been saved and are ready to view."
132
+ output += "\n\n" + "\n".join(html_image_tags) # Append all HTML <img> tags to the output
133
+ else:
134
+ output = "No images were generated."
135
+
136
+ except Exception as e:
137
+ import traceback
138
+ traceback.print_exc()
139
+ output = f"Error {'editing' if input_images else 'generating'} image: {str(e)}"
140
+
141
+ context['output'] = output
142
+ context['messages'] = output_messages
143
+ context['model'] = model
144
+ context['provider'] = provider
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npcsh
3
- Version: 1.1.9
3
+ Version: 1.1.11
4
4
  Summary: npcsh is a command-line toolkit for using AI agents in novel ways.
5
5
  Home-page: https://github.com/NPC-Worldwide/npcsh
6
6
  Author: Christopher Agostino
@@ -0,0 +1,126 @@
1
+ npcsh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ npcsh/_state.py,sha256=usBR6coQKDpDCSqdkuwwvi3YIm0qv1ujjRtHjm7YWz8,104317
3
+ npcsh/alicanto.py,sha256=QCuTtMOgjFkjfrwZZdZBhfp-ETbimlOrXJQiZhClzT0,42160
4
+ npcsh/build.py,sha256=UuId0_rQml40A4U1KuvMekRyfB30s8HiLsXFJjqrBmM,7692
5
+ npcsh/corca.py,sha256=Z2j5z1TNBhtKpShDrPSWKQ1uZ205bqo2dSWenc08gFA,62853
6
+ npcsh/guac.py,sha256=0OrHVSx05r3-9-NgI-u-IZOeLLMpnNj2O21NFnhmtFI,80472
7
+ npcsh/mcp_helpers.py,sha256=9TsCfcquGu_vX4WaKlY3J3P13-uxruQKrXng-jJ5YyY,11176
8
+ npcsh/mcp_server.py,sha256=Lfpabnwi_xu0UudJxQ_YNyyCn2f0_JjzorhWmIeclwY,8777
9
+ npcsh/npc.py,sha256=yqgqZDLwqniIbbDu-vaJf31fWVbOrtgNnFXfjDBk-D8,9853
10
+ npcsh/npcsh.py,sha256=bepoCYVZ0yYW3b1vSYgwwEazamqgHyQ2X7DQw2Tn6Mk,9633
11
+ npcsh/plonk.py,sha256=IfOuiE5FBvk-EIsrWFjGy0SrNywDpn4a49E7seBtEmY,14246
12
+ npcsh/pti.py,sha256=UciiiH2Kz4ERQFy0-FX6BQEU2VxYQEUril-_Cvj76Y0,7853
13
+ npcsh/routes.py,sha256=27rZUwiMK12WuFEDOxLL_F_F8GjmHlFBxKQRuvElrHI,4967
14
+ npcsh/spool.py,sha256=oCive2dbn1o3UGUJnFMzfON6g4bOnauuzyyQBgul6RI,9839
15
+ npcsh/wander.py,sha256=8WOX8az8BXjizXGraEvu-ZVphi6PECKZzo9alTK4gmA,21730
16
+ npcsh/yap.py,sha256=QU-j9eg8zixXG6nyjoIYXsanJ4FjPnzhS4aJ241HLxw,18467
17
+ npcsh/npc_team/alicanto.npc,sha256=y9yDY3lq8ZwxQxpnrgle8w5IJwZqvxDepZFU4OaZCtg,148
18
+ npcsh/npc_team/alicanto.png,sha256=A7xeMbcoKGjlkELxJEVifCEZLVWbOKZarTN5ZFJG-FM,3519858
19
+ npcsh/npc_team/corca.npc,sha256=NtZW1mQ_AMOHlfMCfl8A3uA00UMuHuO95FzRg6kUixo,631
20
+ npcsh/npc_team/corca.png,sha256=0lF70hKu6tY-37YmIPVF2cuaPzvnQ4-UtQOzuAbKEf4,1666776
21
+ npcsh/npc_team/corca_example.png,sha256=p0lVTuwaps4-F-3k4wgp9d897YPyn6FGZugtXMUQjj8,28777
22
+ npcsh/npc_team/foreman.npc,sha256=WqB8jLfBToGmr8c1vip1KOnTHxfXlGXwDUGnZoDMQr0,327
23
+ npcsh/npc_team/frederic.npc,sha256=EE2dOUItp-VKuW3ZMSHffmIEO4evjPcU2W_C4P3WXbY,362
24
+ npcsh/npc_team/frederic4.png,sha256=ll8uoV0npnPp5HVJWv7h0xDSeuq4pqsk_gYGBHLS0VY,1590744
25
+ npcsh/npc_team/guac.png,sha256=MCE7eJuEJwLJEzc9FS7lL62Mm-38jQRHkxXogPfOTuw,211470
26
+ npcsh/npc_team/kadiefa.npc,sha256=Yl5a4wrfe4F2f6Ndw_ukzlVVX7NE9g_mG-3QqJSkg_o,381
27
+ npcsh/npc_team/kadiefa.png,sha256=3CAwL8crKIwJko6o75Z6OYYEEM9Rk--yGzCJg7zoszg,3062528
28
+ npcsh/npc_team/npcsh.ctx,sha256=-jKYaPm2YbZHAGgWAXhyPIwhiNe1H1ZRFg1Zc7tHSxk,1049
29
+ npcsh/npc_team/npcsh_sibiji.png,sha256=9fUqgYMsSHmaH-kBTBQ7N5UCS5-eLZF94Log0O3mtFg,4544
30
+ npcsh/npc_team/plonk.npc,sha256=u1m2a1D512XGQ2kC3eWDAY8Y2IvpkNU73DI_CPE65UE,90
31
+ npcsh/npc_team/plonk.png,sha256=IU5ey-Dl4HEKlwnf75RSWNSHpF8rVqGmdbsa0deL4rQ,2727773
32
+ npcsh/npc_team/plonkjr.npc,sha256=It-i-BEuG0XddKk0d85onk2aJr9Pe5pLnJzNaCWaQIM,87
33
+ npcsh/npc_team/plonkjr.png,sha256=MqLEGwsyECUeODZIti0HQQrMMVxA6XERpW01R06NbpY,2606710
34
+ npcsh/npc_team/sibiji.npc,sha256=Hb4wXKIObKKgibwnio5hLec9yd_9bKDCA87Nm2zijFA,216
35
+ npcsh/npc_team/sibiji.png,sha256=1dlZb7J3E62FcVo9CVOzLb8nu1bIUV7cr97nsFocHCM,35615
36
+ npcsh/npc_team/spool.png,sha256=LWTLkwDxXBfLuSUCX32_lo5yAmLYGsA67Xpsz-7MmWU,2876725
37
+ npcsh/npc_team/yap.png,sha256=_l7UbWnXJdsy4Mx-x5l9DT0R6ize3HTnkwQQnOFlI18,1548649
38
+ npcsh/npc_team/jinxs/code/python.jinx,sha256=lFJubdPVlGxSuUKCxsxjYG4_dnX2ATn8U9ChYKRmL5Q,389
39
+ npcsh/npc_team/jinxs/code/sh.jinx,sha256=CsB1j0T_Ivw_VqVUsuUkq3QXJBV0ppgqqb7AvhQbtbw,1226
40
+ npcsh/npc_team/jinxs/code/sql.jinx,sha256=qKheyMHZQe-YJBisLFwApiwUph0Gn7lbkz_WFueymWA,574
41
+ npcsh/npc_team/jinxs/modes/alicanto.jinx,sha256=MknpYUX0eIvi5vG9gkoTkJvF_LcFbAp_hQ0qkYEBr3c,4014
42
+ npcsh/npc_team/jinxs/modes/corca.jinx,sha256=HTSyjoR2Hc4zEyQudapddOyP3paLcpxhWld5R4XipCk,905
43
+ npcsh/npc_team/jinxs/modes/guac.jinx,sha256=UIVXw8c-m-lh10bxL2yl2n94TQ_SjZSwLP3sLFGv0k4,1616
44
+ npcsh/npc_team/jinxs/modes/plonk.jinx,sha256=teHS1A2Ov5imAWp9oHW1RNUVV2k4cfFQo-ro30mxuS8,2323
45
+ npcsh/npc_team/jinxs/modes/pti.jinx,sha256=Yw32GQS9LvYkukEfjq6R1GLAL6fWACYBz9JuVecZJEo,1126
46
+ npcsh/npc_team/jinxs/modes/spool.jinx,sha256=A4upAI4LnXxYUjY0Rz1_kAhRCDpz08XWPTgisiH06A4,1664
47
+ npcsh/npc_team/jinxs/modes/wander.jinx,sha256=Svc6zjmoXr4BbDg5SN4DB1Byhh75AmIeAItcJCBIlcc,3513
48
+ npcsh/npc_team/jinxs/modes/yap.jinx,sha256=eaI665zjaLH2FUwHoO3iC1Uzo9bGA-a1UMtBRBTEHC0,898
49
+ npcsh/npc_team/jinxs/npc_studio/npc-studio.jinx,sha256=0aY-z399BRIXIL3TLMTcYDiHjDm-krZy0CnYfiskQUo,2234
50
+ npcsh/npc_team/jinxs/utils/agent.jinx,sha256=8aw99XNfslRz2OZIzufptBEKZwyyzdfD9PpC7f2gQYA,529
51
+ npcsh/npc_team/jinxs/utils/chat.jinx,sha256=xhsLIOfjWkwDupKxZH28Jo29so1PQiLtIxaEZexGrUY,532
52
+ npcsh/npc_team/jinxs/utils/compress.jinx,sha256=B2dMsT-jrMWzjQfMhRIuO7afgqj7MJngshz5DBMmu7s,6834
53
+ npcsh/npc_team/jinxs/utils/edit_file.jinx,sha256=jExsHctvapG2xlze6E7ZR3oSLS9hJTYKKd41dQwgOLw,3488
54
+ npcsh/npc_team/jinxs/utils/load_file.jinx,sha256=KdL3nhYWL2-8A0-lN2A2NIe0mAgoc-fIWzpFJnnLPZs,1264
55
+ npcsh/npc_team/jinxs/utils/ots.jinx,sha256=DKoSVgH_ZcmOaZ2-R-Yn80KyCiYgqG25JG6e4wQwP64,2301
56
+ npcsh/npc_team/jinxs/utils/roll.jinx,sha256=RhYhDDdyKcWjVhVSU7dX_DMn5s4rz-nY6pXmtr6tytM,2908
57
+ npcsh/npc_team/jinxs/utils/sample.jinx,sha256=7cWwfAZFgWxaTkIL1gpFFryQ3mjvVjoWYAov-zOFn_E,2237
58
+ npcsh/npc_team/jinxs/utils/search.jinx,sha256=qTICVdk1QrbQ_ulCOaAnbXnGCKk9MgO0MI4MKbDbbRI,5421
59
+ npcsh/npc_team/jinxs/utils/serve.jinx,sha256=D-a-UafymNfAWeLW1sLM_Ef-971SF9TPcUvYu70AIlk,837
60
+ npcsh/npc_team/jinxs/utils/sleep.jinx,sha256=c-7Dn4aLuX7WyBVcvuk3sqcbIutqKIz1N9sBfPNzhck,5301
61
+ npcsh/npc_team/jinxs/utils/trigger.jinx,sha256=YVFPEH6mT9HiAyfPZOCcBpKB033g6K4QCJO0sfgKSQA,2458
62
+ npcsh/npc_team/jinxs/utils/vixynt.jinx,sha256=gsBtTTOtwYkIE43AjOf6U6cc1aLyl9sQiwdM00vrzA4,5662
63
+ npcsh/npc_team/jinxs/utils/core/build.jinx,sha256=QrShGspHwP1z073334vhUIIJZ_3pMJWN_DX_DPPVslU,2771
64
+ npcsh/npc_team/jinxs/utils/core/compile.jinx,sha256=Rjdm5jf3ech1E3cnpLz-o2tbJuVvEoQGAp0FQRAU7qo,2526
65
+ npcsh/npc_team/jinxs/utils/core/help.jinx,sha256=OquhUEgcYZp-gu5Wgl3pOZnswxGQ96RoNG08tHjC9-4,2091
66
+ npcsh/npc_team/jinxs/utils/core/init.jinx,sha256=QBb1uOTvMlD-x3S7zPASH5TBZRwNhMQvK6t3DdC2mVw,1596
67
+ npcsh/npc_team/jinxs/utils/core/jinxs.jinx,sha256=rF432zHrVeccbGKm5tHxd_bZ7OQk355xB6LTlEIXiuI,1269
68
+ npcsh/npc_team/jinxs/utils/core/set.jinx,sha256=hQY_0muEtnWtfXsdK9cPwSvIevCimiJJn1-yhGC_VxM,1381
69
+ npcsh-1.1.11.data/data/npcsh/npc_team/agent.jinx,sha256=8aw99XNfslRz2OZIzufptBEKZwyyzdfD9PpC7f2gQYA,529
70
+ npcsh-1.1.11.data/data/npcsh/npc_team/alicanto.jinx,sha256=MknpYUX0eIvi5vG9gkoTkJvF_LcFbAp_hQ0qkYEBr3c,4014
71
+ npcsh-1.1.11.data/data/npcsh/npc_team/alicanto.npc,sha256=y9yDY3lq8ZwxQxpnrgle8w5IJwZqvxDepZFU4OaZCtg,148
72
+ npcsh-1.1.11.data/data/npcsh/npc_team/alicanto.png,sha256=A7xeMbcoKGjlkELxJEVifCEZLVWbOKZarTN5ZFJG-FM,3519858
73
+ npcsh-1.1.11.data/data/npcsh/npc_team/build.jinx,sha256=QrShGspHwP1z073334vhUIIJZ_3pMJWN_DX_DPPVslU,2771
74
+ npcsh-1.1.11.data/data/npcsh/npc_team/chat.jinx,sha256=xhsLIOfjWkwDupKxZH28Jo29so1PQiLtIxaEZexGrUY,532
75
+ npcsh-1.1.11.data/data/npcsh/npc_team/compile.jinx,sha256=Rjdm5jf3ech1E3cnpLz-o2tbJuVvEoQGAp0FQRAU7qo,2526
76
+ npcsh-1.1.11.data/data/npcsh/npc_team/compress.jinx,sha256=B2dMsT-jrMWzjQfMhRIuO7afgqj7MJngshz5DBMmu7s,6834
77
+ npcsh-1.1.11.data/data/npcsh/npc_team/corca.jinx,sha256=HTSyjoR2Hc4zEyQudapddOyP3paLcpxhWld5R4XipCk,905
78
+ npcsh-1.1.11.data/data/npcsh/npc_team/corca.npc,sha256=NtZW1mQ_AMOHlfMCfl8A3uA00UMuHuO95FzRg6kUixo,631
79
+ npcsh-1.1.11.data/data/npcsh/npc_team/corca.png,sha256=0lF70hKu6tY-37YmIPVF2cuaPzvnQ4-UtQOzuAbKEf4,1666776
80
+ npcsh-1.1.11.data/data/npcsh/npc_team/corca_example.png,sha256=p0lVTuwaps4-F-3k4wgp9d897YPyn6FGZugtXMUQjj8,28777
81
+ npcsh-1.1.11.data/data/npcsh/npc_team/edit_file.jinx,sha256=jExsHctvapG2xlze6E7ZR3oSLS9hJTYKKd41dQwgOLw,3488
82
+ npcsh-1.1.11.data/data/npcsh/npc_team/foreman.npc,sha256=WqB8jLfBToGmr8c1vip1KOnTHxfXlGXwDUGnZoDMQr0,327
83
+ npcsh-1.1.11.data/data/npcsh/npc_team/frederic.npc,sha256=EE2dOUItp-VKuW3ZMSHffmIEO4evjPcU2W_C4P3WXbY,362
84
+ npcsh-1.1.11.data/data/npcsh/npc_team/frederic4.png,sha256=ll8uoV0npnPp5HVJWv7h0xDSeuq4pqsk_gYGBHLS0VY,1590744
85
+ npcsh-1.1.11.data/data/npcsh/npc_team/guac.jinx,sha256=UIVXw8c-m-lh10bxL2yl2n94TQ_SjZSwLP3sLFGv0k4,1616
86
+ npcsh-1.1.11.data/data/npcsh/npc_team/guac.png,sha256=MCE7eJuEJwLJEzc9FS7lL62Mm-38jQRHkxXogPfOTuw,211470
87
+ npcsh-1.1.11.data/data/npcsh/npc_team/help.jinx,sha256=OquhUEgcYZp-gu5Wgl3pOZnswxGQ96RoNG08tHjC9-4,2091
88
+ npcsh-1.1.11.data/data/npcsh/npc_team/init.jinx,sha256=QBb1uOTvMlD-x3S7zPASH5TBZRwNhMQvK6t3DdC2mVw,1596
89
+ npcsh-1.1.11.data/data/npcsh/npc_team/jinxs.jinx,sha256=rF432zHrVeccbGKm5tHxd_bZ7OQk355xB6LTlEIXiuI,1269
90
+ npcsh-1.1.11.data/data/npcsh/npc_team/kadiefa.npc,sha256=Yl5a4wrfe4F2f6Ndw_ukzlVVX7NE9g_mG-3QqJSkg_o,381
91
+ npcsh-1.1.11.data/data/npcsh/npc_team/kadiefa.png,sha256=3CAwL8crKIwJko6o75Z6OYYEEM9Rk--yGzCJg7zoszg,3062528
92
+ npcsh-1.1.11.data/data/npcsh/npc_team/load_file.jinx,sha256=KdL3nhYWL2-8A0-lN2A2NIe0mAgoc-fIWzpFJnnLPZs,1264
93
+ npcsh-1.1.11.data/data/npcsh/npc_team/npc-studio.jinx,sha256=0aY-z399BRIXIL3TLMTcYDiHjDm-krZy0CnYfiskQUo,2234
94
+ npcsh-1.1.11.data/data/npcsh/npc_team/npcsh.ctx,sha256=-jKYaPm2YbZHAGgWAXhyPIwhiNe1H1ZRFg1Zc7tHSxk,1049
95
+ npcsh-1.1.11.data/data/npcsh/npc_team/npcsh_sibiji.png,sha256=9fUqgYMsSHmaH-kBTBQ7N5UCS5-eLZF94Log0O3mtFg,4544
96
+ npcsh-1.1.11.data/data/npcsh/npc_team/ots.jinx,sha256=DKoSVgH_ZcmOaZ2-R-Yn80KyCiYgqG25JG6e4wQwP64,2301
97
+ npcsh-1.1.11.data/data/npcsh/npc_team/plonk.jinx,sha256=teHS1A2Ov5imAWp9oHW1RNUVV2k4cfFQo-ro30mxuS8,2323
98
+ npcsh-1.1.11.data/data/npcsh/npc_team/plonk.npc,sha256=u1m2a1D512XGQ2kC3eWDAY8Y2IvpkNU73DI_CPE65UE,90
99
+ npcsh-1.1.11.data/data/npcsh/npc_team/plonk.png,sha256=IU5ey-Dl4HEKlwnf75RSWNSHpF8rVqGmdbsa0deL4rQ,2727773
100
+ npcsh-1.1.11.data/data/npcsh/npc_team/plonkjr.npc,sha256=It-i-BEuG0XddKk0d85onk2aJr9Pe5pLnJzNaCWaQIM,87
101
+ npcsh-1.1.11.data/data/npcsh/npc_team/plonkjr.png,sha256=MqLEGwsyECUeODZIti0HQQrMMVxA6XERpW01R06NbpY,2606710
102
+ npcsh-1.1.11.data/data/npcsh/npc_team/pti.jinx,sha256=Yw32GQS9LvYkukEfjq6R1GLAL6fWACYBz9JuVecZJEo,1126
103
+ npcsh-1.1.11.data/data/npcsh/npc_team/python.jinx,sha256=lFJubdPVlGxSuUKCxsxjYG4_dnX2ATn8U9ChYKRmL5Q,389
104
+ npcsh-1.1.11.data/data/npcsh/npc_team/roll.jinx,sha256=RhYhDDdyKcWjVhVSU7dX_DMn5s4rz-nY6pXmtr6tytM,2908
105
+ npcsh-1.1.11.data/data/npcsh/npc_team/sample.jinx,sha256=7cWwfAZFgWxaTkIL1gpFFryQ3mjvVjoWYAov-zOFn_E,2237
106
+ npcsh-1.1.11.data/data/npcsh/npc_team/search.jinx,sha256=qTICVdk1QrbQ_ulCOaAnbXnGCKk9MgO0MI4MKbDbbRI,5421
107
+ npcsh-1.1.11.data/data/npcsh/npc_team/serve.jinx,sha256=D-a-UafymNfAWeLW1sLM_Ef-971SF9TPcUvYu70AIlk,837
108
+ npcsh-1.1.11.data/data/npcsh/npc_team/set.jinx,sha256=hQY_0muEtnWtfXsdK9cPwSvIevCimiJJn1-yhGC_VxM,1381
109
+ npcsh-1.1.11.data/data/npcsh/npc_team/sh.jinx,sha256=CsB1j0T_Ivw_VqVUsuUkq3QXJBV0ppgqqb7AvhQbtbw,1226
110
+ npcsh-1.1.11.data/data/npcsh/npc_team/sibiji.npc,sha256=Hb4wXKIObKKgibwnio5hLec9yd_9bKDCA87Nm2zijFA,216
111
+ npcsh-1.1.11.data/data/npcsh/npc_team/sibiji.png,sha256=1dlZb7J3E62FcVo9CVOzLb8nu1bIUV7cr97nsFocHCM,35615
112
+ npcsh-1.1.11.data/data/npcsh/npc_team/sleep.jinx,sha256=c-7Dn4aLuX7WyBVcvuk3sqcbIutqKIz1N9sBfPNzhck,5301
113
+ npcsh-1.1.11.data/data/npcsh/npc_team/spool.jinx,sha256=A4upAI4LnXxYUjY0Rz1_kAhRCDpz08XWPTgisiH06A4,1664
114
+ npcsh-1.1.11.data/data/npcsh/npc_team/spool.png,sha256=LWTLkwDxXBfLuSUCX32_lo5yAmLYGsA67Xpsz-7MmWU,2876725
115
+ npcsh-1.1.11.data/data/npcsh/npc_team/sql.jinx,sha256=qKheyMHZQe-YJBisLFwApiwUph0Gn7lbkz_WFueymWA,574
116
+ npcsh-1.1.11.data/data/npcsh/npc_team/trigger.jinx,sha256=YVFPEH6mT9HiAyfPZOCcBpKB033g6K4QCJO0sfgKSQA,2458
117
+ npcsh-1.1.11.data/data/npcsh/npc_team/vixynt.jinx,sha256=gsBtTTOtwYkIE43AjOf6U6cc1aLyl9sQiwdM00vrzA4,5662
118
+ npcsh-1.1.11.data/data/npcsh/npc_team/wander.jinx,sha256=Svc6zjmoXr4BbDg5SN4DB1Byhh75AmIeAItcJCBIlcc,3513
119
+ npcsh-1.1.11.data/data/npcsh/npc_team/yap.jinx,sha256=eaI665zjaLH2FUwHoO3iC1Uzo9bGA-a1UMtBRBTEHC0,898
120
+ npcsh-1.1.11.data/data/npcsh/npc_team/yap.png,sha256=_l7UbWnXJdsy4Mx-x5l9DT0R6ize3HTnkwQQnOFlI18,1548649
121
+ npcsh-1.1.11.dist-info/licenses/LICENSE,sha256=IKBvAECHP-aCiJtE4cHGCE5Yl0tozYz02PomGeWS3y4,1070
122
+ npcsh-1.1.11.dist-info/METADATA,sha256=QlbxxllPBr5HS5KhALRMzKNZjgwDhFQG1HKO7ZanWj0,25805
123
+ npcsh-1.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
+ npcsh-1.1.11.dist-info/entry_points.txt,sha256=S5yIuGm8ZXQ4siHYgN5gs0J7bxgobSEULXf8L5HaW5o,206
125
+ npcsh-1.1.11.dist-info/top_level.txt,sha256=kHSNgKMCkfjV95-DH0YSp1LLBi0HXdF3w57j7MQON3E,6
126
+ npcsh-1.1.11.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- jinx_name: "breathe"
2
- description: "Condense context on a regular cadence"
3
- inputs: [] # The breathe command takes all relevant context from the NPC's environment
4
- steps:
5
- - name: "condense_context"
6
- engine: "python"
7
- code: |
8
- from npcpy.llm_funcs import breathe
9
-
10
- output_messages = context.get('messages', [])
11
-
12
- # Pass all current context as kwargs to breathe
13
- result = breathe(**context)
14
-
15
- if isinstance(result, dict):
16
- context['output'] = result.get('output', 'Context condensed.')
17
- context['messages'] = result.get('messages', output_messages)
18
- else:
19
- context['output'] = "Context condensation process initiated."
20
- context['messages'] = output_messages
@@ -1,39 +0,0 @@
1
- jinx_name: "flush"
2
- description: "Flush the last N messages from the conversation history."
3
- inputs:
4
- - n: 1 # The number of messages to flush (default to 1).
5
- steps:
6
- - name: "flush_messages"
7
- engine: "python"
8
- code: |
9
- n = int(context.get('n', 1))
10
- output_messages = context.get('messages', [])
11
-
12
- if n <= 0:
13
- context['output'] = "Error: Number of messages must be positive."
14
- context['messages'] = output_messages
15
- exit()
16
-
17
- new_messages = list(output_messages)
18
- original_len = len(new_messages)
19
- removed_count = 0
20
-
21
- if new_messages and new_messages[0].get("role") == "system":
22
- system_message = new_messages[0]
23
- working_messages = new_messages[1:]
24
- num_to_remove = min(n, len(working_messages))
25
- if num_to_remove > 0:
26
- final_messages = [system_message] + working_messages[:-num_to_remove]
27
- removed_count = num_to_remove
28
- else:
29
- final_messages = [system_message]
30
- else:
31
- num_to_remove = min(n, original_len)
32
- if num_to_remove > 0:
33
- final_messages = new_messages[:-num_to_remove]
34
- removed_count = num_to_remove
35
- else:
36
- final_messages = []
37
-
38
- context['output'] = f"Flushed {removed_count} message(s). Context is now {len(final_messages)} messages."
39
- context['messages'] = final_messages
@@ -1,33 +0,0 @@
1
- jinx_name: "plan"
2
- description: "Execute a plan command"
3
- inputs:
4
- - plan_description: "" # Description of the plan to execute.
5
- steps:
6
- - name: "execute_plan"
7
- engine: "python"
8
- code: |
9
- import traceback
10
- from npcpy.work.plan import execute_plan_command
11
-
12
- plan_description = context.get('plan_description')
13
- output_messages = context.get('messages', [])
14
-
15
- if not plan_description or not plan_description.strip():
16
- context['output'] = "Usage: /plan <description_of_plan>"
17
- context['messages'] = output_messages
18
- exit()
19
-
20
- try:
21
- # Pass all current context as kwargs to execute_plan_command
22
- result = execute_plan_command(command=plan_description, **context)
23
-
24
- if isinstance(result, dict):
25
- context['output'] = result.get('output', 'Plan executed.')
26
- context['messages'] = result.get('messages', output_messages)
27
- else:
28
- context['output'] = str(result)
29
- context['messages'] = output_messages
30
- except Exception as e:
31
- traceback.print_exc()
32
- context['output'] = f"Error executing plan: {e}"
33
- context['messages'] = output_messages
@@ -1,20 +0,0 @@
1
- jinx_name: "breathe"
2
- description: "Condense context on a regular cadence"
3
- inputs: [] # The breathe command takes all relevant context from the NPC's environment
4
- steps:
5
- - name: "condense_context"
6
- engine: "python"
7
- code: |
8
- from npcpy.llm_funcs import breathe
9
-
10
- output_messages = context.get('messages', [])
11
-
12
- # Pass all current context as kwargs to breathe
13
- result = breathe(**context)
14
-
15
- if isinstance(result, dict):
16
- context['output'] = result.get('output', 'Context condensed.')
17
- context['messages'] = result.get('messages', output_messages)
18
- else:
19
- context['output'] = "Context condensation process initiated."
20
- context['messages'] = output_messages
@@ -1,39 +0,0 @@
1
- jinx_name: "flush"
2
- description: "Flush the last N messages from the conversation history."
3
- inputs:
4
- - n: 1 # The number of messages to flush (default to 1).
5
- steps:
6
- - name: "flush_messages"
7
- engine: "python"
8
- code: |
9
- n = int(context.get('n', 1))
10
- output_messages = context.get('messages', [])
11
-
12
- if n <= 0:
13
- context['output'] = "Error: Number of messages must be positive."
14
- context['messages'] = output_messages
15
- exit()
16
-
17
- new_messages = list(output_messages)
18
- original_len = len(new_messages)
19
- removed_count = 0
20
-
21
- if new_messages and new_messages[0].get("role") == "system":
22
- system_message = new_messages[0]
23
- working_messages = new_messages[1:]
24
- num_to_remove = min(n, len(working_messages))
25
- if num_to_remove > 0:
26
- final_messages = [system_message] + working_messages[:-num_to_remove]
27
- removed_count = num_to_remove
28
- else:
29
- final_messages = [system_message]
30
- else:
31
- num_to_remove = min(n, original_len)
32
- if num_to_remove > 0:
33
- final_messages = new_messages[:-num_to_remove]
34
- removed_count = num_to_remove
35
- else:
36
- final_messages = []
37
-
38
- context['output'] = f"Flushed {removed_count} message(s). Context is now {len(final_messages)} messages."
39
- context['messages'] = final_messages
@@ -1,33 +0,0 @@
1
- jinx_name: "plan"
2
- description: "Execute a plan command"
3
- inputs:
4
- - plan_description: "" # Description of the plan to execute.
5
- steps:
6
- - name: "execute_plan"
7
- engine: "python"
8
- code: |
9
- import traceback
10
- from npcpy.work.plan import execute_plan_command
11
-
12
- plan_description = context.get('plan_description')
13
- output_messages = context.get('messages', [])
14
-
15
- if not plan_description or not plan_description.strip():
16
- context['output'] = "Usage: /plan <description_of_plan>"
17
- context['messages'] = output_messages
18
- exit()
19
-
20
- try:
21
- # Pass all current context as kwargs to execute_plan_command
22
- result = execute_plan_command(command=plan_description, **context)
23
-
24
- if isinstance(result, dict):
25
- context['output'] = result.get('output', 'Plan executed.')
26
- context['messages'] = result.get('messages', output_messages)
27
- else:
28
- context['output'] = str(result)
29
- context['messages'] = output_messages
30
- except Exception as e:
31
- traceback.print_exc()
32
- context['output'] = f"Error executing plan: {e}"
33
- context['messages'] = output_messages
@@ -1,19 +0,0 @@
1
- jinx_name: sh
2
- description: Execute bash queries. Should be used to grep for file contents, list directories, explore information to answer user questions more practically.
3
- inputs:
4
- - bash_command
5
- steps:
6
- - engine: python
7
- code: |
8
- import subprocess
9
- import os
10
- cmd = '{{bash_command}}'
11
- def run_command(cmd):
12
- process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13
- stdout, stderr = process.communicate()
14
- if stderr:
15
- print(f"Error: {stderr.decode('utf-8')}")
16
- return stderr
17
- return stdout
18
- result = run_command(cmd)
19
- output = result.decode('utf-8')
@@ -1,36 +0,0 @@
1
- jinx_name: "trigger"
2
- description: "Execute a trigger command"
3
- inputs:
4
- - trigger_description: "" # Required description of the trigger to execute.
5
- steps:
6
- - name: "execute_trigger"
7
- engine: "python"
8
- code: |
9
- import traceback
10
- from npcpy.work.trigger import execute_trigger_command
11
-
12
- trigger_description = context.get('trigger_description')
13
- output_messages = context.get('messages', [])
14
-
15
- if not trigger_description or not trigger_description.strip():
16
- context['output'] = "Usage: /trigger <trigger_description>"
17
- context['messages'] = output_messages
18
- exit()
19
-
20
- try:
21
- # Pass all current context as kwargs to execute_trigger_command
22
- result = execute_trigger_command(command=trigger_description, **context)
23
-
24
- if isinstance(result, dict):
25
- context['output'] = result.get('output', 'Trigger executed.')
26
- context['messages'] = result.get('messages', output_messages)
27
- else:
28
- context['output'] = str(result)
29
- context['messages'] = output_messages
30
- except NameError:
31
- context['output'] = "Trigger function (execute_trigger_command) not available."
32
- context['messages'] = output_messages
33
- except Exception as e:
34
- traceback.print_exc()
35
- context['output'] = f"Error executing trigger: {e}"
36
- context['messages'] = output_messages
@@ -1,117 +0,0 @@
1
- jinx_name: "vixynt"
2
- description: "Generates images from text descriptions or edits existing ones."
3
- inputs:
4
- - prompt
5
- - model: ""
6
- - provider: ""
7
- - output_name: ""
8
- - attachments: ""
9
- - n_images: 1
10
- - height: 1024
11
- - width: 1024
12
- steps:
13
- - name: "generate_or_edit_image"
14
- engine: "python"
15
- code: |
16
- import os
17
- import base64
18
- from io import BytesIO
19
- from datetime import datetime
20
- from PIL import Image
21
- from npcpy.llm_funcs import gen_image
22
-
23
- # Extract inputs from context
24
- image_prompt = context.get('prompt', '').strip()
25
- output_name = context.get('output_name')
26
- attachments_str = context.get('attachments')
27
- n_images = int(context.get('n_images', 1))
28
- height = int(context.get('height', 1024))
29
- width = int(context.get('width', 1024))
30
- model = context.get('model')
31
- provider = context.get('provider')
32
-
33
- input_images = []
34
- if attachments_str and attachments_str.strip():
35
- input_images = [p.strip() for p in attachments_str.split(',')]
36
-
37
- # Use NPC's model/provider as fallback
38
- if not model and npc and npc.model:
39
- model = npc.model
40
- if not provider and npc and npc.provider:
41
- provider = npc.provider
42
-
43
- # Final fallbacks
44
- if not model:
45
- model = "runwayml/stable-diffusion-v1-5"
46
- if not provider:
47
- provider = "diffusers"
48
-
49
- output_messages = context.get('messages', [])
50
-
51
- if not image_prompt:
52
- context['output'] = "Error: No prompt provided for image generation."
53
- context['messages'] = output_messages
54
- exit()
55
-
56
- try:
57
- # Generate image(s)
58
- result = gen_image(
59
- prompt=image_prompt,
60
- model=model,
61
- provider=provider,
62
- npc=npc,
63
- height=height,
64
- width=width,
65
- n_images=n_images,
66
- input_images=input_images if input_images else None
67
- )
68
-
69
- # Ensure we have a list of images
70
- if not isinstance(result, list):
71
- images_list = [result] if result is not None else []
72
- else:
73
- images_list = result
74
-
75
- saved_files = []
76
-
77
- for i, image in enumerate(images_list):
78
- if image is None:
79
- continue
80
-
81
- # Determine output filename
82
- if output_name and output_name.strip():
83
- base_name, ext = os.path.splitext(os.path.expanduser(output_name))
84
- if not ext:
85
- ext = ".png"
86
- current_output_file = f"{base_name}_{i}{ext}" if len(images_list) > 1 else f"{base_name}{ext}"
87
- else:
88
- os.makedirs(os.path.expanduser("~/.npcsh/images/"), exist_ok=True)
89
- current_output_file = (
90
- os.path.expanduser("~/.npcsh/images/")
91
- + f"image_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{i}.png"
92
- )
93
-
94
- # Save image to file
95
- image.save(current_output_file)
96
- saved_files.append(current_output_file)
97
-
98
- if saved_files:
99
- if input_images:
100
- output = f"Image(s) edited and saved to: {', '.join(saved_files)}"
101
- else:
102
- output = f"Image(s) generated and saved to: {', '.join(saved_files)}"
103
-
104
- # DO NOT include base64 data - just reference the file paths
105
- output += f"\n\nThe image files have been saved and are ready to view."
106
- else:
107
- output = "No images were generated."
108
-
109
- except Exception as e:
110
- import traceback
111
- traceback.print_exc()
112
- output = f"Error {'editing' if input_images else 'generating'} image: {str(e)}"
113
-
114
- context['output'] = output
115
- context['messages'] = output_messages
116
- context['model'] = model
117
- context['provider'] = provider