thinking-prompt 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. thinking_prompt-0.1.0/.gitignore +75 -0
  2. thinking_prompt-0.1.0/LICENSE +21 -0
  3. thinking_prompt-0.1.0/PKG-INFO +198 -0
  4. thinking_prompt-0.1.0/README.md +161 -0
  5. thinking_prompt-0.1.0/docs/demo.gif +0 -0
  6. thinking_prompt-0.1.0/examples/basic.py +64 -0
  7. thinking_prompt-0.1.0/examples/chat_demo.py +84 -0
  8. thinking_prompt-0.1.0/examples/demo.py +82 -0
  9. thinking_prompt-0.1.0/examples/demo_animated_separator.py +133 -0
  10. thinking_prompt-0.1.0/examples/demo_messages_during_thinking.py +112 -0
  11. thinking_prompt-0.1.0/examples/demo_progress_line.py +168 -0
  12. thinking_prompt-0.1.0/examples/demo_showcase.py +170 -0
  13. thinking_prompt-0.1.0/examples/progress_demo.py +85 -0
  14. thinking_prompt-0.1.0/examples/streaming.py +80 -0
  15. thinking_prompt-0.1.0/pyproject.toml +89 -0
  16. thinking_prompt-0.1.0/tests/__init__.py +1 -0
  17. thinking_prompt-0.1.0/tests/conftest.py +66 -0
  18. thinking_prompt-0.1.0/tests/test_display.py +457 -0
  19. thinking_prompt-0.1.0/tests/test_history.py +182 -0
  20. thinking_prompt-0.1.0/tests/test_thinking.py +284 -0
  21. thinking_prompt-0.1.0/tests/test_thread_safety.py +187 -0
  22. thinking_prompt-0.1.0/tests/test_types.py +173 -0
  23. thinking_prompt-0.1.0/thinking_prompt/__init__.py +67 -0
  24. thinking_prompt-0.1.0/thinking_prompt/app_info.py +171 -0
  25. thinking_prompt-0.1.0/thinking_prompt/display.py +356 -0
  26. thinking_prompt-0.1.0/thinking_prompt/history.py +97 -0
  27. thinking_prompt-0.1.0/thinking_prompt/layout.py +451 -0
  28. thinking_prompt-0.1.0/thinking_prompt/py.typed +0 -0
  29. thinking_prompt-0.1.0/thinking_prompt/session.py +820 -0
  30. thinking_prompt-0.1.0/thinking_prompt/styles.py +121 -0
  31. thinking_prompt-0.1.0/thinking_prompt/thinking.py +307 -0
  32. thinking_prompt-0.1.0/thinking_prompt/types.py +143 -0
@@ -0,0 +1,75 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ build/
9
+ develop-eggs/
10
+ dist/
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+
24
+ # PyInstaller
25
+ *.manifest
26
+ *.spec
27
+
28
+ # Installer logs
29
+ pip-log.txt
30
+ pip-delete-this-directory.txt
31
+
32
+ # Unit test / coverage reports
33
+ htmlcov/
34
+ .tox/
35
+ .nox/
36
+ .coverage
37
+ .coverage.*
38
+ .cache
39
+ nosetests.xml
40
+ coverage.xml
41
+ *.cover
42
+ *.py,cover
43
+ .hypothesis/
44
+ .pytest_cache/
45
+
46
+ # Translations
47
+ *.mo
48
+ *.pot
49
+
50
+ # Environments
51
+ .env
52
+ .venv
53
+ env/
54
+ venv/
55
+ ENV/
56
+ env.bak/
57
+ venv.bak/
58
+
59
+ # IDE
60
+ .idea/
61
+ .vscode/
62
+ *.swp
63
+ *.swo
64
+ *~
65
+
66
+ # macOS
67
+ .DS_Store
68
+
69
+ # Project specific
70
+ notes/
71
+ plans/
72
+ .claude/
73
+ claude.md
74
+ GEMINI.md
75
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.4
2
+ Name: thinking-prompt
3
+ Version: 0.1.0
4
+ Summary: A prompt_toolkit extension that adds a thinking box above the prompt
5
+ Project-URL: Homepage, https://github.com/shoom1/thinking-prompt
6
+ Project-URL: Repository, https://github.com/shoom1/thinking-prompt
7
+ Author: Andrey Shiryaev
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: ai,cli,prompt_toolkit,terminal,thinking
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Terminals
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: prompt-toolkit>=3.0.0
25
+ Provides-Extra: all
26
+ Requires-Dist: pygments>=2.0; extra == 'all'
27
+ Requires-Dist: rich>=13.0; extra == 'all'
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
32
+ Requires-Dist: pytest>=7.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
34
+ Provides-Extra: rich
35
+ Requires-Dist: rich>=13.0; extra == 'rich'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # thinking-prompt
39
+
40
+ A prompt_toolkit extension that adds a "thinking box" above the prompt for displaying AI thinking/processing content with real-time streaming updates.
41
+
42
+ ![Demo](docs/demo.gif)
43
+
44
+ ## Features
45
+
46
+ - **Thinking Box**: A collapsible area above the prompt that shows processing/thinking content
47
+ - **Real-time Streaming**: Content updates in real-time as your callback returns new content
48
+ - **Fullscreen Mode**: Optional fullscreen mode with chat history (disabled by default)
49
+ - **Animated Separator**: Configurable animated indicator showing thinking is in progress
50
+ - **Rich Output**: Support for markdown rendering and syntax-highlighted code blocks
51
+ - **Customizable Styles**: Full control over colors and styling
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install thinking-prompt
57
+ ```
58
+
59
+ For markdown and code highlighting support:
60
+ ```bash
61
+ pip install thinking-prompt[all]
62
+ ```
63
+
64
+ ## Quick Start
65
+
66
+ ```python
67
+ import asyncio
68
+ from thinking_prompt import ThinkingPromptSession, AppInfo
69
+
70
+ async def main():
71
+ app_info = AppInfo(name="MyApp", version="1.0.0")
72
+ session = ThinkingPromptSession(app_info=app_info, message=">>> ")
73
+
74
+ @session.on_input
75
+ async def handle(text: str):
76
+ if not text.strip():
77
+ return
78
+
79
+ # Use context manager for clean thinking management
80
+ async with session.thinking() as content:
81
+ content.append("Processing...\n")
82
+ await asyncio.sleep(0.5)
83
+ content.append("Done!\n")
84
+
85
+ session.add_response(f"You said: {text}")
86
+
87
+ await session.run_async()
88
+
89
+ if __name__ == "__main__":
90
+ asyncio.run(main())
91
+ ```
92
+
93
+ ## Key Bindings
94
+
95
+ | Key | Action |
96
+ |-----|--------|
97
+ | Ctrl+T | Expand/collapse thinking box (in prompt mode) |
98
+ | Ctrl+E | Toggle fullscreen mode (when enabled) |
99
+ | Ctrl+C | Cancel current operation or exit |
100
+ | Ctrl+D | Exit application |
101
+
102
+ ## API Reference
103
+
104
+ ### ThinkingPromptSession
105
+
106
+ The main class for creating a thinking-enabled prompt session.
107
+
108
+ ```python
109
+ session = ThinkingPromptSession(
110
+ message=">>> ", # Prompt message
111
+ app_info=AppInfo(...), # App metadata and configuration
112
+ max_thinking_height=15, # Max lines when collapsed
113
+ enable_status_bar=True, # Show status bar
114
+ echo_input=True, # Echo user input to console
115
+ )
116
+ ```
117
+
118
+ ### Thinking API
119
+
120
+ **Context Manager (recommended):**
121
+ ```python
122
+ async with session.thinking() as content:
123
+ content.append("Step 1...\n")
124
+ await asyncio.sleep(0.5)
125
+ content.append("Step 2...\n")
126
+ # Automatically finishes when exiting context
127
+ ```
128
+
129
+ **Manual control:**
130
+ ```python
131
+ # Start with a content callback
132
+ chunks = []
133
+ session.start_thinking(lambda: ''.join(chunks))
134
+
135
+ chunks.append("Processing...\n")
136
+ await asyncio.sleep(0.5)
137
+
138
+ # Finish and optionally echo to console
139
+ session.finish_thinking(add_to_history=True, echo_to_console=True)
140
+ ```
141
+
142
+ ### Output Methods
143
+
144
+ ```python
145
+ # Plain text response
146
+ session.add_response("Hello, world!")
147
+
148
+ # Markdown (requires rich)
149
+ session.add_response("# Title\n- Item 1\n- Item 2", markdown=True)
150
+
151
+ # Syntax-highlighted code (requires pygments)
152
+ session.add_code("def hello(): return 'world'", language="python")
153
+
154
+ # Status messages
155
+ session.add_success("Operation completed")
156
+ session.add_warning("Rate limit approaching")
157
+ session.add_error("Connection failed")
158
+ session.add_message("system", "Connecting to server...")
159
+ ```
160
+
161
+ ### AppInfo Configuration
162
+
163
+ ```python
164
+ app_info = AppInfo(
165
+ name="MyApp",
166
+ version="1.0.0",
167
+ welcome_message="Welcome to MyApp!", # Optional custom welcome
168
+
169
+ # Key bindings
170
+ fullscreen_key="c-e", # Ctrl+E for fullscreen
171
+ expand_key="c-t", # Ctrl+T for expand/collapse
172
+
173
+ # Feature flags
174
+ fullscreen_enabled=False, # Enable fullscreen mode
175
+ echo_thinking=True, # Echo thinking to console after completion
176
+
177
+ # Thinking animation
178
+ thinking_text="Thinking", # Text in separator
179
+ thinking_animation=("⠋", "⠙", "⠹", ...), # Animation frames
180
+ thinking_animation_position="before", # "before" or "after" text
181
+ )
182
+ ```
183
+
184
+ ## Examples
185
+
186
+ See the `examples/` directory for complete demos:
187
+
188
+ - `basic.py` - Simple thinking box usage
189
+ - `demo.py` - Interactive demo with simulated AI thinking
190
+ - `streaming.py` - Character-by-character streaming
191
+ - `progress_demo.py` - Progress bar with callback
192
+ - `demo_progress_line.py` - In-place progress updates
193
+ - `demo_messages_during_thinking.py` - Output messages during thinking
194
+ - `demo_animated_separator.py` - Different animation configurations
195
+
196
+ ## License
197
+
198
+ MIT
@@ -0,0 +1,161 @@
1
+ # thinking-prompt
2
+
3
+ A prompt_toolkit extension that adds a "thinking box" above the prompt for displaying AI thinking/processing content with real-time streaming updates.
4
+
5
+ ![Demo](docs/demo.gif)
6
+
7
+ ## Features
8
+
9
+ - **Thinking Box**: A collapsible area above the prompt that shows processing/thinking content
10
+ - **Real-time Streaming**: Content updates in real-time as your callback returns new content
11
+ - **Fullscreen Mode**: Optional fullscreen mode with chat history (disabled by default)
12
+ - **Animated Separator**: Configurable animated indicator showing thinking is in progress
13
+ - **Rich Output**: Support for markdown rendering and syntax-highlighted code blocks
14
+ - **Customizable Styles**: Full control over colors and styling
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install thinking-prompt
20
+ ```
21
+
22
+ For markdown and code highlighting support:
23
+ ```bash
24
+ pip install thinking-prompt[all]
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```python
30
+ import asyncio
31
+ from thinking_prompt import ThinkingPromptSession, AppInfo
32
+
33
+ async def main():
34
+ app_info = AppInfo(name="MyApp", version="1.0.0")
35
+ session = ThinkingPromptSession(app_info=app_info, message=">>> ")
36
+
37
+ @session.on_input
38
+ async def handle(text: str):
39
+ if not text.strip():
40
+ return
41
+
42
+ # Use context manager for clean thinking management
43
+ async with session.thinking() as content:
44
+ content.append("Processing...\n")
45
+ await asyncio.sleep(0.5)
46
+ content.append("Done!\n")
47
+
48
+ session.add_response(f"You said: {text}")
49
+
50
+ await session.run_async()
51
+
52
+ if __name__ == "__main__":
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ ## Key Bindings
57
+
58
+ | Key | Action |
59
+ |-----|--------|
60
+ | Ctrl+T | Expand/collapse thinking box (in prompt mode) |
61
+ | Ctrl+E | Toggle fullscreen mode (when enabled) |
62
+ | Ctrl+C | Cancel current operation or exit |
63
+ | Ctrl+D | Exit application |
64
+
65
+ ## API Reference
66
+
67
+ ### ThinkingPromptSession
68
+
69
+ The main class for creating a thinking-enabled prompt session.
70
+
71
+ ```python
72
+ session = ThinkingPromptSession(
73
+ message=">>> ", # Prompt message
74
+ app_info=AppInfo(...), # App metadata and configuration
75
+ max_thinking_height=15, # Max lines when collapsed
76
+ enable_status_bar=True, # Show status bar
77
+ echo_input=True, # Echo user input to console
78
+ )
79
+ ```
80
+
81
+ ### Thinking API
82
+
83
+ **Context Manager (recommended):**
84
+ ```python
85
+ async with session.thinking() as content:
86
+ content.append("Step 1...\n")
87
+ await asyncio.sleep(0.5)
88
+ content.append("Step 2...\n")
89
+ # Automatically finishes when exiting context
90
+ ```
91
+
92
+ **Manual control:**
93
+ ```python
94
+ # Start with a content callback
95
+ chunks = []
96
+ session.start_thinking(lambda: ''.join(chunks))
97
+
98
+ chunks.append("Processing...\n")
99
+ await asyncio.sleep(0.5)
100
+
101
+ # Finish and optionally echo to console
102
+ session.finish_thinking(add_to_history=True, echo_to_console=True)
103
+ ```
104
+
105
+ ### Output Methods
106
+
107
+ ```python
108
+ # Plain text response
109
+ session.add_response("Hello, world!")
110
+
111
+ # Markdown (requires rich)
112
+ session.add_response("# Title\n- Item 1\n- Item 2", markdown=True)
113
+
114
+ # Syntax-highlighted code (requires pygments)
115
+ session.add_code("def hello(): return 'world'", language="python")
116
+
117
+ # Status messages
118
+ session.add_success("Operation completed")
119
+ session.add_warning("Rate limit approaching")
120
+ session.add_error("Connection failed")
121
+ session.add_message("system", "Connecting to server...")
122
+ ```
123
+
124
+ ### AppInfo Configuration
125
+
126
+ ```python
127
+ app_info = AppInfo(
128
+ name="MyApp",
129
+ version="1.0.0",
130
+ welcome_message="Welcome to MyApp!", # Optional custom welcome
131
+
132
+ # Key bindings
133
+ fullscreen_key="c-e", # Ctrl+E for fullscreen
134
+ expand_key="c-t", # Ctrl+T for expand/collapse
135
+
136
+ # Feature flags
137
+ fullscreen_enabled=False, # Enable fullscreen mode
138
+ echo_thinking=True, # Echo thinking to console after completion
139
+
140
+ # Thinking animation
141
+ thinking_text="Thinking", # Text in separator
142
+ thinking_animation=("⠋", "⠙", "⠹", ...), # Animation frames
143
+ thinking_animation_position="before", # "before" or "after" text
144
+ )
145
+ ```
146
+
147
+ ## Examples
148
+
149
+ See the `examples/` directory for complete demos:
150
+
151
+ - `basic.py` - Simple thinking box usage
152
+ - `demo.py` - Interactive demo with simulated AI thinking
153
+ - `streaming.py` - Character-by-character streaming
154
+ - `progress_demo.py` - Progress bar with callback
155
+ - `demo_progress_line.py` - In-place progress updates
156
+ - `demo_messages_during_thinking.py` - Output messages during thinking
157
+ - `demo_animated_separator.py` - Different animation configurations
158
+
159
+ ## License
160
+
161
+ MIT
Binary file
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Basic example demonstrating the ThinkingPromptSession.
4
+
5
+ Run this script to see the thinking box in action:
6
+ python examples/basic.py
7
+ """
8
+ import asyncio
9
+
10
+ from thinking_prompt import ThinkingPromptSession, AppInfo
11
+
12
+
13
+ async def main():
14
+ """Main async function demonstrating thinking box features."""
15
+ app_info = AppInfo(name="BasicDemo", version="1.0.0")
16
+ session = ThinkingPromptSession(
17
+ app_info=app_info,
18
+ message=">>> ",
19
+ max_thinking_height=10,
20
+ )
21
+
22
+ @session.on_input
23
+ async def handle(text: str):
24
+ """Handle user input with simulated thinking."""
25
+ if not text.strip():
26
+ return
27
+
28
+ # Use a list for O(1) append
29
+ chunks = []
30
+
31
+ def get_content():
32
+ return ''.join(chunks)
33
+
34
+ # Start thinking mode with content callback
35
+ session.start_thinking(get_content)
36
+
37
+ # Update thinking box with streaming content
38
+ chunks.append("Processing your input...\n")
39
+ await asyncio.sleep(0.3)
40
+
41
+ # Simulate token-by-token processing
42
+ words = text.split()
43
+ for i, word in enumerate(words):
44
+ chunks.append(f" Token {i + 1}: {word}\n")
45
+ await asyncio.sleep(0.15)
46
+
47
+ chunks.append("\nAnalysis complete!\n")
48
+ await asyncio.sleep(0.5)
49
+
50
+ # Finish thinking - content moves to console
51
+ session.finish_thinking()
52
+
53
+ # Add response to chat history
54
+ session.add_response(f"You entered {len(words)} word(s): {text}")
55
+
56
+ # Run the session
57
+ await session.run_async()
58
+
59
+
60
+ if __name__ == "__main__":
61
+ try:
62
+ asyncio.run(main())
63
+ except KeyboardInterrupt:
64
+ pass
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Chat-like demo of ThinkingPromptSession.
4
+
5
+ This example demonstrates:
6
+ - Welcome message display at startup
7
+ - Decorator-style handler registration
8
+ - Thinking box appearing above the prompt during processing
9
+ - Real-time streaming updates in the thinking box
10
+ - Expand/collapse thinking box with Ctrl+T
11
+
12
+ Run:
13
+ python examples/chat_demo.py
14
+ """
15
+ import asyncio
16
+
17
+ from thinking_prompt import ThinkingPromptSession, AppInfo
18
+
19
+
20
+ async def main():
21
+ app_info = AppInfo(name="ChatDemo", version="1.0.0")
22
+ session = ThinkingPromptSession(
23
+ app_info=app_info,
24
+ message="You: ",
25
+ max_thinking_height=5,
26
+ status_text="Ctrl+C: cancel | Ctrl+D: exit",
27
+ )
28
+
29
+ @session.on_input
30
+ async def handle(user_input: str):
31
+ """Process user input with simulated thinking."""
32
+ if not user_input.strip():
33
+ return
34
+
35
+ # Use a list for O(1) append
36
+ chunks = []
37
+
38
+ def get_content():
39
+ return ''.join(chunks)
40
+
41
+ # Start thinking mode
42
+ session.start_thinking(get_content)
43
+
44
+ # Phase 1: Initial analysis
45
+ chunks.append("Analyzing your input...\n")
46
+ await asyncio.sleep(0.4)
47
+
48
+ # Phase 2: Show what we're processing
49
+ chunks.append(f"Received: \"{user_input}\"\n")
50
+ await asyncio.sleep(0.3)
51
+
52
+ # Phase 3: Simulated reasoning steps (more than max_thinking_height to show truncation)
53
+ steps = [
54
+ "Step 1: Parsing input...",
55
+ "Step 2: Tokenizing text...",
56
+ "Step 3: Analyzing semantics...",
57
+ "Step 4: Processing concepts...",
58
+ "Step 5: Building context...",
59
+ "Step 6: Generating candidates...",
60
+ "Step 7: Ranking responses...",
61
+ "Step 8: Selecting best response...",
62
+ ]
63
+
64
+ for step in steps:
65
+ chunks.append(f" {step}\n")
66
+ await asyncio.sleep(0.3)
67
+
68
+ # Phase 4: Done
69
+ chunks.append("\nDone.\n")
70
+ await asyncio.sleep(0.3)
71
+
72
+ # Finish thinking - adds thinking content to history
73
+ session.finish_thinking()
74
+
75
+ # Add the actual response (separate from thinking)
76
+ response = f"I understood your message: '{user_input[:50]}{'...' if len(user_input) > 50 else ''}'"
77
+ session.add_response(response)
78
+
79
+ # Run the session - handler already registered with @on_input
80
+ await session.run_async()
81
+
82
+
83
+ if __name__ == "__main__":
84
+ asyncio.run(main())
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Interactive demo of ThinkingPromptSession.
4
+
5
+ This example simulates an AI assistant that "thinks" before responding.
6
+ The thinking box appears after you enter input, updates in real-time,
7
+ and then transitions to permanent console output.
8
+
9
+ Run:
10
+ python examples/demo.py
11
+ """
12
+ import asyncio
13
+
14
+ from thinking_prompt import ThinkingPromptSession, AppInfo
15
+
16
+
17
+ async def main():
18
+ app_info = AppInfo(name="InteractiveDemo", version="1.0.0")
19
+ session = ThinkingPromptSession(
20
+ app_info=app_info,
21
+ message="You: ",
22
+ max_thinking_height=12,
23
+ )
24
+
25
+ @session.on_input
26
+ async def handle(user_input: str):
27
+ """Process user input with simulated thinking."""
28
+ if not user_input.strip():
29
+ return
30
+
31
+ # Use a list for O(1) append
32
+ chunks = []
33
+
34
+ def get_content():
35
+ return ''.join(chunks)
36
+
37
+ # Start thinking mode
38
+ session.start_thinking(get_content)
39
+
40
+ # Update thinking box in real-time
41
+ chunks.append("Analyzing your input...\n")
42
+ await asyncio.sleep(0.4)
43
+
44
+ chunks.append(f"Input received: \"{user_input}\"\n\n")
45
+ await asyncio.sleep(0.3)
46
+
47
+ # Simulated reasoning steps
48
+ steps = [
49
+ "Step 1: Parsing input structure...",
50
+ "Step 2: Identifying key concepts...",
51
+ "Step 3: Generating response...",
52
+ ]
53
+
54
+ for step in steps:
55
+ chunks.append(f"{step}\n")
56
+ await asyncio.sleep(0.5)
57
+
58
+ # Stream the "response" character by character
59
+ chunks.append("\nResponse: ")
60
+ await asyncio.sleep(0.2)
61
+
62
+ preview = user_input[:30] + ('...' if len(user_input) > 30 else '')
63
+ response = f"I understood your message about '{preview}'"
64
+ for char in response:
65
+ chunks.append(char)
66
+ await asyncio.sleep(0.03)
67
+
68
+ chunks.append("\n")
69
+ await asyncio.sleep(0.3)
70
+
71
+ # Finish - content is printed to console (if not in fullscreen)
72
+ session.finish_thinking()
73
+
74
+ # Add response to chat history
75
+ session.add_response(response)
76
+
77
+ # Run the session with the registered handler
78
+ await session.run_async()
79
+
80
+
81
+ if __name__ == "__main__":
82
+ asyncio.run(main())