danielrosehill commited on
Commit
bc3c7d8
·
1 Parent(s): 0bbea4b

Add images and updates with proper LFS tracking

Browse files
Files changed (7) hide show
  1. README.md +2 -1
  2. app.py +56 -44
  3. banner.jpg +3 -0
  4. bot-meetup.png +3 -0
  5. design/1.png +3 -0
  6. design/2.png +3 -0
  7. design/3.png +3 -0
README.md CHANGED
@@ -1,6 +1,5 @@
1
  ---
2
  title: Text Transformation Model
3
- emoji: 🚀
4
  colorFrom: purple
5
  colorTo: pink
6
  sdk: gradio
@@ -12,6 +11,8 @@ short_description: Single turn text transformation pattern
12
 
13
  # Text Transformation Model
14
 
 
 
15
  Pattern Space for in-out single-turn text transformation workflows based on a system prompt.
16
 
17
  Mode of operation: user-defined system prompt + single-turn workflow definition concatenate to an enriched system prompt ensuring reliable single turn adherence.
 
1
  ---
2
  title: Text Transformation Model
 
3
  colorFrom: purple
4
  colorTo: pink
5
  sdk: gradio
 
11
 
12
  # Text Transformation Model
13
 
14
+ ![Banner](banner.jpg)
15
+
16
  Pattern Space for in-out single-turn text transformation workflows based on a system prompt.
17
 
18
  Mode of operation: user-defined system prompt + single-turn workflow definition concatenate to an enriched system prompt ensuring reliable single turn adherence.
app.py CHANGED
@@ -4,17 +4,6 @@ import os
4
  from typing import Optional, Tuple
5
 
6
  def transform_text(input_text: str, system_prompt: str, api_key: str) -> Tuple[str, str]:
7
- """
8
- Transform input text using OpenAI API with the provided system prompt.
9
-
10
- Args:
11
- input_text: The text to transform
12
- system_prompt: User-defined system prompt
13
- api_key: OpenAI API key
14
-
15
- Returns:
16
- Tuple of (output_text, cleared_input_text)
17
- """
18
  if not api_key.strip():
19
  return "Error: Please provide your OpenAI API key.", input_text
20
 
@@ -25,17 +14,14 @@ def transform_text(input_text: str, system_prompt: str, api_key: str) -> Tuple[s
25
  return "Error: Please provide a system prompt.", input_text
26
 
27
  try:
28
- # Initialize OpenAI client with user's API key
29
  client = openai.OpenAI(api_key=api_key.strip())
30
 
31
- # Append workflow instruction to user's system prompt
32
  enhanced_system_prompt = f"""{system_prompt.strip()}
33
 
34
  IMPORTANT: This is a single-turn text transformation workflow interface. You must respond with the complete transformed text only, without any additional commentary, explanations, or formatting before or after the content."""
35
 
36
- # Make API call
37
  response = client.chat.completions.create(
38
- model="gpt-4o-mini", # Using cost-effective model
39
  messages=[
40
  {"role": "system", "content": enhanced_system_prompt},
41
  {"role": "user", "content": input_text.strip()}
@@ -45,8 +31,6 @@ IMPORTANT: This is a single-turn text transformation workflow interface. You mus
45
  )
46
 
47
  output_text = response.choices[0].message.content
48
-
49
- # Return output and clear input for next use
50
  return output_text, ""
51
 
52
  except openai.AuthenticationError:
@@ -59,10 +43,8 @@ IMPORTANT: This is a single-turn text transformation workflow interface. You mus
59
  return f"Error: {str(e)}", input_text
60
 
61
  def copy_to_clipboard(text: str) -> str:
62
- """Return the text for copying (Gradio handles the clipboard functionality)"""
63
  return text
64
 
65
- # Custom CSS for better styling
66
  custom_css = """
67
  .main-container {
68
  max-width: 1200px;
@@ -122,25 +104,31 @@ with gr.Blocks(css=custom_css, title="Text Transformation Model", theme=gr.theme
122
  Single-Turn Text Transformer (In, Out)
123
  </h1>
124
  <p style="font-size: 1.2em; color: #666; margin-bottom: 20px;">
125
- A pattern for simple system prompt defined single turn text transformations.
126
  </p>
127
  </div>
128
  """)
129
 
130
  with gr.Tabs():
131
  with gr.Tab("Transform Text"):
132
- # API Key Section
133
  with gr.Row():
134
- with gr.Column():
 
 
 
 
 
 
 
 
 
135
  api_key_input = gr.Textbox(
136
  label="OpenAI API Key",
137
  placeholder="Enter your OpenAI API key (sk-...)",
138
  type="password",
139
  info="Your API key is stored locally in your browser for this session."
140
  )
141
-
142
- with gr.Row():
143
- with gr.Column():
144
  system_prompt_input = gr.Textbox(
145
  label="System Prompt",
146
  placeholder="Enter your system prompt here (e.g., 'Translate the following text to French', 'Summarize this text in bullet points', etc.)",
@@ -148,7 +136,6 @@ with gr.Blocks(css=custom_css, title="Text Transformation Model", theme=gr.theme
148
  info="Define how the AI should transform your input text. This prompt will be enhanced automatically for single-turn processing."
149
  )
150
 
151
- # Input/Output Section
152
  with gr.Row():
153
  with gr.Column(scale=1):
154
  input_text = gr.Textbox(
@@ -179,11 +166,10 @@ with gr.Blocks(css=custom_css, title="Text Transformation Model", theme=gr.theme
179
  elem_classes=["copy-button"]
180
  )
181
 
182
- # Event handlers
183
  transform_btn.click(
184
  fn=transform_text,
185
  inputs=[input_text, system_prompt_input, api_key_input],
186
- outputs=[output_text, input_text] # Clear input after transformation
187
  )
188
 
189
  copy_btn.click(
@@ -194,46 +180,72 @@ with gr.Blocks(css=custom_css, title="Text Transformation Model", theme=gr.theme
194
 
195
  with gr.Tab("About"):
196
  gr.Markdown("""
197
- ## Single Turn Text Transformer
198
 
199
  - By: [Daniel Rosehill](https://danielrosehill.com) (11-Sep-2025)
200
 
201
- This Space provides a simple implementation of an extremely foundational but effective use for large language models (LLMs): taking a text and transforming it into something else using a sytsem prompt for guidance!
202
 
203
- I call this Space a "model" of a "pattern" because an almost limitless variety of simple UIs can be developed around this priciple by simply alternating the underlying system prompt (which in this demo is made editable with a short concatenated element).
204
 
205
- I call tools like these the great forgotten gems of the AI landscape: just as this AI use-case reached a high degree of stability, maturity, and cost-effectivenss it has already been lumped into the bucket of legacy tech.
206
 
207
  ## What Do You Call An Assistant That's Not An Agent?
208
 
209
  Single turn text transformation tools like this (which lack, I argue, even a proper name!) are stateless and non-agentic and thus locked out of the glamorous agent landscape. They are single turn and non-conversational so are clearly not chatbots. At best, they might be described as "assistants" - to the extent that agents have not already usurped the term. But as assistants now connote something much more agentic, they might lack no matter name than "using AI to transform text."
210
 
211
- Text transformers have vast application: they can be used to change the person or level of formality of text; to retsructure text from free-flowing formats into defined templates; or to clean up voice captured text, received from speech to text models, for downstream use in other systems. The model is very simple: the user prompt provides the text to be transformed and the system prompt provides the model with the desired transformation. The system prompt can also encapsulate few-shot examples to boost reliability. However, these workflows tend to execute well without even this safeguard.
212
 
213
  ## "Lived Experience"
214
 
215
  I have implemented plenty of these.
216
 
217
- To provide one pedestrian example: I have an agent like this whose task is to depersonalise system prompts so that I can open source them without random users getting addressed as "Daniel" or assumed to also live in Jerusalem. The system prompt asks the agent to take my system prompt and remove it of any details unique to my life - replace 'Daniel' with 'the user', etc. It's a simple in-out workflow that can (of course) be scripted and run in batches and programatically but which is just as often more useful through a simple browser UI. And it doesn't get much simpler than a form in and form out!
218
 
219
  Other reasons why I love these tools:
220
 
221
- - They leverage a very foundational and intended use of LLMs. This is not a frontier use or cojoling LLMs into doing something we hope might work. It was what they were designed for. If you share my conviction that tools usually are best at what they were built for, this one's a winner.
222
- - They are forgiving. You don't need a model branded as having PhD level reasoning to get these to work reliably well. Hence, they are cheap. And a huge advantage of affordabilty: you can spend plenty of time working on great system prompting until you achieve the perfect desired type of text reformatting.
223
- - They are great, too, for just demonstrating the utility of AI away from the hype cycle. They do something that even the most advanced RegEx patterns cant'. They work great locally, too.
224
  - You just need a prompt: No tooling, no MCP integrations. Unless you're trying to transform encyclopedias in one go, they won't challenge the context window of modern models. In, out.
 
 
 
 
 
 
 
225
 
226
-
227
-
228
-
229
- """, elem_id="about-content")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
- # Add JavaScript for clipboard functionality and local storage
232
  gr.HTML("""
233
  <script>
234
- // Local storage for API key and system prompt
235
  document.addEventListener('DOMContentLoaded', function() {
236
- // Load saved API key and system prompt
237
  const savedApiKey = localStorage.getItem('openai_api_key');
238
  const savedSystemPrompt = localStorage.getItem('system_prompt');
239
 
 
4
  from typing import Optional, Tuple
5
 
6
  def transform_text(input_text: str, system_prompt: str, api_key: str) -> Tuple[str, str]:
 
 
 
 
 
 
 
 
 
 
 
7
  if not api_key.strip():
8
  return "Error: Please provide your OpenAI API key.", input_text
9
 
 
14
  return "Error: Please provide a system prompt.", input_text
15
 
16
  try:
 
17
  client = openai.OpenAI(api_key=api_key.strip())
18
 
 
19
  enhanced_system_prompt = f"""{system_prompt.strip()}
20
 
21
  IMPORTANT: This is a single-turn text transformation workflow interface. You must respond with the complete transformed text only, without any additional commentary, explanations, or formatting before or after the content."""
22
 
 
23
  response = client.chat.completions.create(
24
+ model="gpt-4o-mini",
25
  messages=[
26
  {"role": "system", "content": enhanced_system_prompt},
27
  {"role": "user", "content": input_text.strip()}
 
31
  )
32
 
33
  output_text = response.choices[0].message.content
 
 
34
  return output_text, ""
35
 
36
  except openai.AuthenticationError:
 
43
  return f"Error: {str(e)}", input_text
44
 
45
  def copy_to_clipboard(text: str) -> str:
 
46
  return text
47
 
 
48
  custom_css = """
49
  .main-container {
50
  max-width: 1200px;
 
104
  Single-Turn Text Transformer (In, Out)
105
  </h1>
106
  <p style="font-size: 1.2em; color: #666; margin-bottom: 20px;">
107
+ A pattern for simple form-based, system prompt defined, single turn text transformation UIs.
108
  </p>
109
  </div>
110
  """)
111
 
112
  with gr.Tabs():
113
  with gr.Tab("Transform Text"):
 
114
  with gr.Row():
115
+ with gr.Column(scale=1):
116
+ gr.Image(
117
+ value="banner.jpg",
118
+ show_label=False,
119
+ show_download_button=False,
120
+ interactive=False,
121
+ container=False
122
+ )
123
+
124
+ with gr.Column(scale=2):
125
  api_key_input = gr.Textbox(
126
  label="OpenAI API Key",
127
  placeholder="Enter your OpenAI API key (sk-...)",
128
  type="password",
129
  info="Your API key is stored locally in your browser for this session."
130
  )
131
+
 
 
132
  system_prompt_input = gr.Textbox(
133
  label="System Prompt",
134
  placeholder="Enter your system prompt here (e.g., 'Translate the following text to French', 'Summarize this text in bullet points', etc.)",
 
136
  info="Define how the AI should transform your input text. This prompt will be enhanced automatically for single-turn processing."
137
  )
138
 
 
139
  with gr.Row():
140
  with gr.Column(scale=1):
141
  input_text = gr.Textbox(
 
166
  elem_classes=["copy-button"]
167
  )
168
 
 
169
  transform_btn.click(
170
  fn=transform_text,
171
  inputs=[input_text, system_prompt_input, api_key_input],
172
+ outputs=[output_text, input_text]
173
  )
174
 
175
  copy_btn.click(
 
180
 
181
  with gr.Tab("About"):
182
  gr.Markdown("""
183
+ ## Single Turn Text Transformer
184
 
185
  - By: [Daniel Rosehill](https://danielrosehill.com) (11-Sep-2025)
186
 
187
+ This Space provides a simple implementation of an extremely foundational but effective use for large language models (LLMs): taking a text and transforming it into something else using a system prompt for guidance!
188
 
189
+ I call this Space a "model" of a "pattern" because an almost limitless variety of simple UIs can be developed around this principle by simply alternating the underlying system prompt (which in this demo is made editable with a short concatenated element).
190
 
191
+ I call tools like these the great forgotten gems of the AI landscape: just as this AI use-case reached a high degree of stability, maturity, and cost-effectiveness it has already been lumped into the bucket of legacy tech.
192
 
193
  ## What Do You Call An Assistant That's Not An Agent?
194
 
195
  Single turn text transformation tools like this (which lack, I argue, even a proper name!) are stateless and non-agentic and thus locked out of the glamorous agent landscape. They are single turn and non-conversational so are clearly not chatbots. At best, they might be described as "assistants" - to the extent that agents have not already usurped the term. But as assistants now connote something much more agentic, they might lack no matter name than "using AI to transform text."
196
 
197
+ Text transformers have vast application: they can be used to change the person or level of formality of text; to restructure text from free-flowing formats into defined templates; or to clean up voice captured text, received from speech to text models, for downstream use in other systems. The model is very simple: the user prompt provides the text to be transformed and the system prompt provides the model with the desired transformation. The system prompt can also encapsulate few-shot examples to boost reliability. However, these workflows tend to execute well without even this safeguard.
198
 
199
  ## "Lived Experience"
200
 
201
  I have implemented plenty of these.
202
 
203
+ To provide one pedestrian example: I have an agent like this whose task is to depersonalise system prompts so that I can open source them without random users getting addressed as "Daniel" or assumed to also live in Jerusalem. The system prompt asks the agent to take my system prompt and remove it of any details unique to my life - replace 'Daniel' with 'the user', etc. It's a simple in-out workflow that can (of course) be scripted and run in batches and programmatically but which is just as often more useful through a simple browser UI. And it doesn't get much simpler than a form in and form out!
204
 
205
  Other reasons why I love these tools:
206
 
207
+ - They leverage a very foundational and intended use of LLMs. This is not a frontier use or cajoling LLMs into doing something we hope might work. It was what they were designed for. If you share my conviction that tools usually are best at what they were built for, this one's a winner.
208
+ - They are forgiving. You don't need a model branded as having PhD level reasoning to get these to work reliably well. Hence, they are cheap. And a huge advantage of affordability: you can spend plenty of time working on great system prompting until you achieve the perfect desired type of text reformatting.
209
+ - They are great, too, for just demonstrating the utility of AI away from the hype cycle. They do something that even the most advanced RegEx patterns can't. They work great locally, too.
210
  - You just need a prompt: No tooling, no MCP integrations. Unless you're trying to transform encyclopedias in one go, they won't challenge the context window of modern models. In, out.
211
+ """)
212
+
213
+ with gr.Tab("Design"):
214
+ gr.Markdown("""
215
+ ## Prompt Design for Single Turn Adherence
216
+
217
+ Effective prompt design patterns for non-JSON constrained prompting systems to ensure reliable single-turn text transformation workflows.
218
 
219
+ Instruction here: *IMPORTANT: This is a single-turn text transformation workflow interface. You must respond with the complete transformed text only, without any additional commentary, explanations, or formatting before or after the content.*
220
+ """)
221
+
222
+ gr.Image(
223
+ value="design/1.png",
224
+ show_label=False,
225
+ show_download_button=False,
226
+ interactive=False,
227
+ width=600
228
+ )
229
+
230
+ gr.Image(
231
+ value="design/2.png",
232
+ show_label=False,
233
+ show_download_button=False,
234
+ interactive=False,
235
+ width=600
236
+ )
237
+
238
+ gr.Image(
239
+ value="design/3.png",
240
+ show_label=False,
241
+ show_download_button=False,
242
+ interactive=False,
243
+ width=600
244
+ )
245
 
 
246
  gr.HTML("""
247
  <script>
 
248
  document.addEventListener('DOMContentLoaded', function() {
 
249
  const savedApiKey = localStorage.getItem('openai_api_key');
250
  const savedSystemPrompt = localStorage.getItem('system_prompt');
251
 
banner.jpg ADDED

Git LFS Details

  • SHA256: 787015c7dbec8ae550a704e62a0108532ecab4199a01bd9783cab90c6077ed39
  • Pointer size: 131 Bytes
  • Size of remote file: 599 kB
bot-meetup.png ADDED

Git LFS Details

  • SHA256: 5016b8b723ca9e32d4dc362287faa92a231909f924353bc3b7d24b9822eee241
  • Pointer size: 131 Bytes
  • Size of remote file: 718 kB
design/1.png ADDED

Git LFS Details

  • SHA256: 60d11487c9413de2dd187584e6a4c7f43cd6989a945c43cf621f9f4dc9307bc3
  • Pointer size: 131 Bytes
  • Size of remote file: 351 kB
design/2.png ADDED

Git LFS Details

  • SHA256: f4defb1125ff249af1fdf983a4fd87ad3a3d17d706686a95556d1a567b8cf7ba
  • Pointer size: 131 Bytes
  • Size of remote file: 325 kB
design/3.png ADDED

Git LFS Details

  • SHA256: 12d838e5afd784562a508edc352bb87c38295e817bfdbb8ea4edaad19d20d419
  • Pointer size: 131 Bytes
  • Size of remote file: 316 kB