appkit-assistant 0.15.1__tar.gz → 0.15.2__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 (31) hide show
  1. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/PKG-INFO +1 -1
  2. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/pyproject.toml +1 -1
  3. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processors/openai_responses_processor.py +11 -2
  4. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/message.py +56 -0
  5. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/thread.py +48 -21
  6. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/state/thread_state.py +9 -13
  7. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/.gitignore +0 -0
  8. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/README.md +0 -0
  9. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/docs/assistant.png +0 -0
  10. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/mcp_auth_service.py +0 -0
  11. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/model_manager.py +0 -0
  12. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/models.py +0 -0
  13. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processor.py +0 -0
  14. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processors/lorem_ipsum_processor.py +0 -0
  15. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processors/openai_base.py +0 -0
  16. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processors/openai_chat_completion_processor.py +0 -0
  17. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/processors/perplexity_processor.py +0 -0
  18. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/repositories.py +0 -0
  19. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/backend/system_prompt_cache.py +0 -0
  20. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/__init__.py +0 -0
  21. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/composer.py +0 -0
  22. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/composer_key_handler.py +0 -0
  23. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/mcp_server_dialogs.py +0 -0
  24. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/mcp_server_table.py +0 -0
  25. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/system_prompt_editor.py +0 -0
  26. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/threadlist.py +0 -0
  27. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/components/tools_modal.py +0 -0
  28. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/configuration.py +0 -0
  29. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/state/mcp_server_state.py +0 -0
  30. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/state/system_prompt_state.py +0 -0
  31. {appkit_assistant-0.15.1 → appkit_assistant-0.15.2}/src/appkit_assistant/state/thread_list_state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: appkit-assistant
3
- Version: 0.15.1
3
+ Version: 0.15.2
4
4
  Summary: Add your description here
5
5
  Project-URL: Homepage, https://github.com/jenreh/appkit
6
6
  Project-URL: Documentation, https://github.com/jenreh/appkit/tree/main/docs
@@ -7,7 +7,7 @@ dependencies = [
7
7
  "reflex>=0.8.22",
8
8
  ]
9
9
  name = "appkit-assistant"
10
- version = "0.15.1"
10
+ version = "0.15.2"
11
11
  description = "Add your description here"
12
12
  readme = "README.md"
13
13
  authors = [{ name = "Jens Rehpöhler" }]
@@ -84,8 +84,17 @@ class OpenAIResponsesProcessor(BaseOpenAIProcessor):
84
84
  },
85
85
  )
86
86
  except Exception as e:
87
- logger.error("Error during response processing: %s", e)
88
- # Continue to yield auth chunks if any
87
+ error_msg = str(e)
88
+ logger.error("Error during response processing: %s", error_msg)
89
+ # Yield error chunk to show user-friendly error message
90
+ yield Chunk(
91
+ type=ChunkType.ERROR,
92
+ text=f"Ein Fehler ist aufgetreten: {error_msg}",
93
+ chunk_metadata={
94
+ "source": "responses_api",
95
+ "error_type": type(e).__name__,
96
+ },
97
+ )
89
98
 
90
99
  # After processing (or on error), yield any pending auth requirements
91
100
  logger.debug(
@@ -229,6 +229,54 @@ class MessageComponent:
229
229
  style=message_styles,
230
230
  )
231
231
 
232
+ @staticmethod
233
+ def error_message(message: str) -> rx.Component:
234
+ return rx.hstack(
235
+ rx.avatar(
236
+ fallback="!",
237
+ size="3",
238
+ variant="soft",
239
+ radius="full",
240
+ margin_top="16px",
241
+ color_scheme="red",
242
+ ),
243
+ rx.callout(
244
+ message,
245
+ icon="triangle-alert",
246
+ color_scheme="red",
247
+ max_width="90%",
248
+ size="1",
249
+ padding="0.5em",
250
+ border_radius="9px",
251
+ margin_top="18px",
252
+ ),
253
+ style=message_styles,
254
+ )
255
+
256
+ @staticmethod
257
+ def system_message(message: str) -> rx.Component:
258
+ return rx.hstack(
259
+ rx.avatar(
260
+ fallback="⚙",
261
+ size="3",
262
+ variant="soft",
263
+ radius="full",
264
+ margin_top="16px",
265
+ color_scheme="gray",
266
+ ),
267
+ rx.callout(
268
+ message,
269
+ icon="info",
270
+ color_scheme="gray",
271
+ max_width="90%",
272
+ size="1",
273
+ padding="0.5em",
274
+ border_radius="9px",
275
+ margin_top="18px",
276
+ ),
277
+ style=message_styles,
278
+ )
279
+
232
280
  @staticmethod
233
281
  def render_message(
234
282
  message: Message,
@@ -245,6 +293,14 @@ class MessageComponent:
245
293
  MessageType.ASSISTANT,
246
294
  MessageComponent.assistant_message(message),
247
295
  ),
296
+ (
297
+ MessageType.ERROR,
298
+ MessageComponent.error_message(message.text),
299
+ ),
300
+ (
301
+ MessageType.SYSTEM,
302
+ MessageComponent.system_message(message.text),
303
+ ),
248
304
  MessageComponent.info_message(message.text),
249
305
  )
250
306
  )
@@ -177,77 +177,104 @@ class Assistant:
177
177
  return;
178
178
  }
179
179
  window._mcpOAuthListenerInstalled = true;
180
- var processing = false;
180
+ var lastProcessedTimestamp = 0;
181
181
 
182
182
  function getCurrentUserId() {
183
183
  var el = document.getElementById('mcp-oauth-user-id');
184
184
  return el ? el.value : '';
185
185
  }
186
186
  function processOAuthResult(data) {
187
- if (processing) {
188
- console.log('[OAuth] Already processing, skip');
187
+ // Simple timestamp-based debouncing
188
+ var now = Date.now();
189
+ if (data.timestamp && data.timestamp === lastProcessedTimestamp) {
190
+ console.log('[OAuth] Already processed this timestamp, skip');
189
191
  return false;
190
192
  }
191
- processing = true;
193
+ lastProcessedTimestamp = data.timestamp || now;
192
194
 
193
195
  var currentUserId = getCurrentUserId();
194
196
  console.log('[OAuth] Processing, userId:', data.userId,
195
- 'current:', currentUserId);
197
+ 'current:', currentUserId, 'timestamp:', data.timestamp);
198
+
196
199
  // Security: only process if user_id matches (or not set)
197
200
  if (data.userId && currentUserId &&
198
201
  String(data.userId) !== String(currentUserId)) {
199
202
  console.log('[OAuth] Ignoring - user mismatch');
200
- processing = false;
201
203
  return false;
202
204
  }
205
+
203
206
  window._mcpOAuthData = data;
204
- var btn = document.getElementById(
205
- 'mcp-oauth-success-trigger'
206
- );
207
+ console.log('[OAuth] Stored data in window._mcpOAuthData');
208
+
209
+ var btn = document.getElementById('mcp-oauth-success-trigger');
207
210
  if (btn) {
208
211
  console.log('[OAuth] Clicking trigger button');
209
212
  btn.click();
213
+ console.log('[OAuth] Button clicked successfully');
214
+ } else {
215
+ console.error('[OAuth] Trigger button not found!');
210
216
  }
211
- // Reset after short delay to allow for page navigation
212
- setTimeout(function() { processing = false; }, 5000);
213
217
  return true;
214
218
  }
219
+
215
220
  function checkLocalStorage() {
216
- if (processing) return false;
217
221
  var stored = localStorage.getItem('mcp-oauth-result');
218
222
  if (stored) {
219
- console.log('[OAuth] Found in localStorage');
223
+ console.log('[OAuth] Found in localStorage:', stored);
220
224
  try {
221
225
  var data = JSON.parse(stored);
222
226
  if (data.type === 'mcp-oauth-success') {
227
+ console.log('[OAuth] Valid OAuth data, removing from localStorage');
223
228
  localStorage.removeItem('mcp-oauth-result');
224
229
  return processOAuthResult(data);
225
230
  }
226
- } catch(e) { console.error('[OAuth] Parse error:', e); }
231
+ } catch(e) {
232
+ console.error('[OAuth] Parse error:', e);
233
+ }
227
234
  }
228
235
  return false;
229
236
  }
237
+
230
238
  console.log('[OAuth] Installing listeners');
239
+
231
240
  window.addEventListener('storage', function(event) {
241
+ console.log('[OAuth] Storage event:', event.key);
232
242
  if (event.key === 'mcp-oauth-result') {
233
- checkLocalStorage();
243
+ setTimeout(checkLocalStorage, 100);
234
244
  }
235
245
  });
246
+
236
247
  window.addEventListener('focus', function() {
237
- checkLocalStorage();
248
+ console.log('[OAuth] Window focus event');
249
+ setTimeout(checkLocalStorage, 100);
238
250
  });
251
+
239
252
  document.addEventListener('visibilitychange', function() {
240
- if (!document.hidden) checkLocalStorage();
253
+ if (!document.hidden) {
254
+ console.log('[OAuth] Document visible');
255
+ setTimeout(checkLocalStorage, 100);
256
+ }
241
257
  });
242
- var intervalId = setInterval(function() {
243
- if (checkLocalStorage()) clearInterval(intervalId);
244
- }, 2000);
245
- checkLocalStorage();
258
+
246
259
  window.addEventListener('message', function(event) {
260
+ console.log('[OAuth] postMessage received:', event.data);
247
261
  if (event.data && event.data.type === 'mcp-oauth-success') {
262
+ console.log('[OAuth] Processing postMessage data');
248
263
  processOAuthResult(event.data);
249
264
  }
250
265
  });
266
+
267
+ // Aggressive polling - check every 500ms
268
+ var intervalId = setInterval(function() {
269
+ if (checkLocalStorage()) {
270
+ console.log('[OAuth] Success via polling, clearing interval');
271
+ clearInterval(intervalId);
272
+ }
273
+ }, 500);
274
+
275
+ // Initial check
276
+ console.log('[OAuth] Initial localStorage check');
277
+ checkLocalStorage();
251
278
  })();
252
279
  """
253
280
  ),
@@ -952,25 +952,21 @@ class ThreadState(rx.State):
952
952
  # Remove the incomplete assistant message from the failed attempt
953
953
  if self.messages and self.messages[-1].type == MessageType.ASSISTANT:
954
954
  self.messages = self.messages[:-1]
955
- # Add success message
956
- self.messages.append(
957
- Message(
958
- text=f"Erfolgreich mit {server_name} verbunden. "
959
- "Anfrage wird erneut gesendet...",
960
- type=MessageType.INFO,
961
- )
955
+ # Show success toast instead of adding to messages
956
+ yield rx.toast.success(
957
+ f"Erfolgreich mit {server_name} verbunden. "
958
+ "Anfrage wird erneut gesendet...",
959
+ position="top-right",
962
960
  )
963
961
  # Resend the original message by setting prompt and yielding the event
964
962
  self.prompt = pending_message
965
963
  self._skip_user_message = True # User message already in list
966
964
  yield ThreadState.submit_message
967
965
  else:
968
- # No pending message - just show success
969
- self.messages.append(
970
- Message(
971
- text=f"Erfolgreich mit {server_name} verbunden.",
972
- type=MessageType.INFO,
973
- )
966
+ # No pending message - just show success toast
967
+ yield rx.toast.success(
968
+ f"Erfolgreich mit {server_name} verbunden.",
969
+ position="top-right",
974
970
  )
975
971
 
976
972
  @rx.event