npcsh 1.1.22__py3-none-any.whl → 1.1.23__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 (172) hide show
  1. npcsh/_state.py +272 -120
  2. npcsh/benchmark/npcsh_agent.py +77 -240
  3. npcsh/benchmark/templates/install-npcsh.sh.j2 +12 -4
  4. npcsh/config.py +5 -2
  5. npcsh/npc_team/alicanto.npc +4 -8
  6. npcsh/npc_team/corca.npc +5 -11
  7. npcsh/npc_team/frederic.npc +4 -6
  8. npcsh/npc_team/guac.npc +4 -4
  9. npcsh/npc_team/jinxs/lib/core/delegate.jinx +1 -1
  10. npcsh/npc_team/jinxs/lib/core/edit_file.jinx +1 -1
  11. npcsh/npc_team/jinxs/lib/core/sh.jinx +1 -1
  12. npcsh/npc_team/jinxs/lib/core/skill.jinx +59 -0
  13. npcsh/npc_team/jinxs/lib/utils/help.jinx +194 -10
  14. npcsh/npc_team/jinxs/lib/utils/init.jinx +528 -37
  15. npcsh/npc_team/jinxs/lib/utils/jinxs.jinx +0 -1
  16. npcsh/npc_team/jinxs/lib/utils/serve.jinx +938 -21
  17. npcsh-1.1.22.data/data/npcsh/npc_team/config_tui.jinx → npcsh/npc_team/jinxs/modes/config.jinx +1 -1
  18. npcsh/npc_team/jinxs/modes/convene.jinx +76 -3
  19. npcsh/npc_team/jinxs/modes/crond.jinx +818 -0
  20. npcsh/npc_team/jinxs/modes/plonk.jinx +76 -14
  21. npcsh/npc_team/jinxs/modes/roll.jinx +368 -55
  22. npcsh/npc_team/jinxs/modes/skills.jinx +621 -0
  23. npcsh/npc_team/jinxs/modes/yap.jinx +504 -30
  24. npcsh/npc_team/jinxs/skills/code-review/SKILL.md +45 -0
  25. npcsh/npc_team/jinxs/skills/debugging/SKILL.md +44 -0
  26. npcsh/npc_team/jinxs/skills/git-workflow.jinx +44 -0
  27. npcsh/npc_team/kadiefa.npc +4 -5
  28. npcsh/npc_team/npcsh.ctx +16 -0
  29. npcsh/npc_team/plonk.npc +5 -9
  30. npcsh/npc_team/sibiji.npc +13 -5
  31. npcsh/npcsh.py +1 -0
  32. npcsh/routes.py +0 -4
  33. npcsh/yap.py +22 -4
  34. npcsh-1.1.23.data/data/npcsh/npc_team/SKILL.md +44 -0
  35. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.npc +4 -8
  36. npcsh/npc_team/jinxs/modes/config_tui.jinx → npcsh-1.1.23.data/data/npcsh/npc_team/config.jinx +1 -1
  37. npcsh-1.1.23.data/data/npcsh/npc_team/convene.jinx +670 -0
  38. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca.npc +5 -11
  39. npcsh-1.1.23.data/data/npcsh/npc_team/crond.jinx +818 -0
  40. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/delegate.jinx +1 -1
  41. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/edit_file.jinx +1 -1
  42. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/frederic.npc +4 -6
  43. npcsh-1.1.23.data/data/npcsh/npc_team/git-workflow.jinx +44 -0
  44. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.npc +4 -4
  45. npcsh-1.1.23.data/data/npcsh/npc_team/help.jinx +236 -0
  46. npcsh-1.1.23.data/data/npcsh/npc_team/init.jinx +532 -0
  47. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/jinxs.jinx +0 -1
  48. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kadiefa.npc +4 -5
  49. npcsh-1.1.23.data/data/npcsh/npc_team/npcsh.ctx +34 -0
  50. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.jinx +76 -14
  51. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.npc +5 -9
  52. npcsh-1.1.23.data/data/npcsh/npc_team/roll.jinx +378 -0
  53. npcsh-1.1.23.data/data/npcsh/npc_team/serve.jinx +943 -0
  54. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sh.jinx +1 -1
  55. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sibiji.npc +13 -5
  56. npcsh-1.1.23.data/data/npcsh/npc_team/skill.jinx +59 -0
  57. npcsh-1.1.23.data/data/npcsh/npc_team/skills.jinx +621 -0
  58. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/yap.jinx +504 -30
  59. {npcsh-1.1.22.dist-info → npcsh-1.1.23.dist-info}/METADATA +168 -7
  60. npcsh-1.1.23.dist-info/RECORD +216 -0
  61. npcsh/npc_team/jinxs/incognide/add_tab.jinx +0 -11
  62. npcsh/npc_team/jinxs/incognide/close_pane.jinx +0 -9
  63. npcsh/npc_team/jinxs/incognide/close_tab.jinx +0 -10
  64. npcsh/npc_team/jinxs/incognide/confirm.jinx +0 -10
  65. npcsh/npc_team/jinxs/incognide/focus_pane.jinx +0 -9
  66. npcsh/npc_team/jinxs/incognide/list_panes.jinx +0 -8
  67. npcsh/npc_team/jinxs/incognide/navigate.jinx +0 -10
  68. npcsh/npc_team/jinxs/incognide/notify.jinx +0 -10
  69. npcsh/npc_team/jinxs/incognide/open_pane.jinx +0 -13
  70. npcsh/npc_team/jinxs/incognide/read_pane.jinx +0 -9
  71. npcsh/npc_team/jinxs/incognide/run_terminal.jinx +0 -10
  72. npcsh/npc_team/jinxs/incognide/send_message.jinx +0 -10
  73. npcsh/npc_team/jinxs/incognide/split_pane.jinx +0 -12
  74. npcsh/npc_team/jinxs/incognide/switch_npc.jinx +0 -10
  75. npcsh/npc_team/jinxs/incognide/switch_tab.jinx +0 -10
  76. npcsh/npc_team/jinxs/incognide/write_file.jinx +0 -11
  77. npcsh/npc_team/jinxs/incognide/zen_mode.jinx +0 -9
  78. npcsh/npc_team/jinxs/lib/core/convene.jinx +0 -232
  79. npcsh-1.1.22.data/data/npcsh/npc_team/add_tab.jinx +0 -11
  80. npcsh-1.1.22.data/data/npcsh/npc_team/close_pane.jinx +0 -9
  81. npcsh-1.1.22.data/data/npcsh/npc_team/close_tab.jinx +0 -10
  82. npcsh-1.1.22.data/data/npcsh/npc_team/confirm.jinx +0 -10
  83. npcsh-1.1.22.data/data/npcsh/npc_team/convene.jinx +0 -232
  84. npcsh-1.1.22.data/data/npcsh/npc_team/focus_pane.jinx +0 -9
  85. npcsh-1.1.22.data/data/npcsh/npc_team/help.jinx +0 -52
  86. npcsh-1.1.22.data/data/npcsh/npc_team/init.jinx +0 -41
  87. npcsh-1.1.22.data/data/npcsh/npc_team/list_panes.jinx +0 -8
  88. npcsh-1.1.22.data/data/npcsh/npc_team/navigate.jinx +0 -10
  89. npcsh-1.1.22.data/data/npcsh/npc_team/notify.jinx +0 -10
  90. npcsh-1.1.22.data/data/npcsh/npc_team/npcsh.ctx +0 -18
  91. npcsh-1.1.22.data/data/npcsh/npc_team/open_pane.jinx +0 -13
  92. npcsh-1.1.22.data/data/npcsh/npc_team/read_pane.jinx +0 -9
  93. npcsh-1.1.22.data/data/npcsh/npc_team/roll.jinx +0 -65
  94. npcsh-1.1.22.data/data/npcsh/npc_team/run_terminal.jinx +0 -10
  95. npcsh-1.1.22.data/data/npcsh/npc_team/send_message.jinx +0 -10
  96. npcsh-1.1.22.data/data/npcsh/npc_team/serve.jinx +0 -26
  97. npcsh-1.1.22.data/data/npcsh/npc_team/split_pane.jinx +0 -12
  98. npcsh-1.1.22.data/data/npcsh/npc_team/switch_npc.jinx +0 -10
  99. npcsh-1.1.22.data/data/npcsh/npc_team/switch_tab.jinx +0 -10
  100. npcsh-1.1.22.data/data/npcsh/npc_team/write_file.jinx +0 -11
  101. npcsh-1.1.22.data/data/npcsh/npc_team/zen_mode.jinx +0 -9
  102. npcsh-1.1.22.dist-info/RECORD +0 -240
  103. /npcsh/npc_team/jinxs/{incognide → lib/utils}/incognide.jinx +0 -0
  104. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.jinx +0 -0
  105. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/alicanto.png +0 -0
  106. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/arxiv.jinx +0 -0
  107. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/benchmark.jinx +0 -0
  108. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/browser_action.jinx +0 -0
  109. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/browser_screenshot.jinx +0 -0
  110. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/build.jinx +0 -0
  111. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/chat.jinx +0 -0
  112. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/click.jinx +0 -0
  113. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/close_browser.jinx +0 -0
  114. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/cmd.jinx +0 -0
  115. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/compile.jinx +0 -0
  116. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/compress.jinx +0 -0
  117. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca.jinx +0 -0
  118. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca.png +0 -0
  119. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/corca_example.png +0 -0
  120. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/db_search.jinx +0 -0
  121. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/file_search.jinx +0 -0
  122. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/frederic4.png +0 -0
  123. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/git.jinx +0 -0
  124. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.jinx +0 -0
  125. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/guac.png +0 -0
  126. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/incognide.jinx +0 -0
  127. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kadiefa.png +0 -0
  128. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/key_press.jinx +0 -0
  129. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/kg.jinx +0 -0
  130. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/launch_app.jinx +0 -0
  131. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/load_file.jinx +0 -0
  132. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/memories.jinx +0 -0
  133. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/models.jinx +0 -0
  134. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
  135. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/nql.jinx +0 -0
  136. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/open_browser.jinx +0 -0
  137. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/ots.jinx +0 -0
  138. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/papers.jinx +0 -0
  139. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/paste.jinx +0 -0
  140. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonk.png +0 -0
  141. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/plonkjr.png +0 -0
  142. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/pti.jinx +0 -0
  143. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/python.jinx +0 -0
  144. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/reattach.jinx +0 -0
  145. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sample.jinx +0 -0
  146. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/screenshot.jinx +0 -0
  147. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/set.jinx +0 -0
  148. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/setup.jinx +0 -0
  149. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/shh.jinx +0 -0
  150. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sibiji.png +0 -0
  151. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sleep.jinx +0 -0
  152. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/spool.jinx +0 -0
  153. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/spool.png +0 -0
  154. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sql.jinx +0 -0
  155. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/switch.jinx +0 -0
  156. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/switches.jinx +0 -0
  157. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/sync.jinx +0 -0
  158. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/team.jinx +0 -0
  159. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/teamviz.jinx +0 -0
  160. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/trigger.jinx +0 -0
  161. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/type_text.jinx +0 -0
  162. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/usage.jinx +0 -0
  163. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/verbose.jinx +0 -0
  164. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/vixynt.jinx +0 -0
  165. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/wait.jinx +0 -0
  166. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/wander.jinx +0 -0
  167. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/web_search.jinx +0 -0
  168. {npcsh-1.1.22.data → npcsh-1.1.23.data}/data/npcsh/npc_team/yap.png +0 -0
  169. {npcsh-1.1.22.dist-info → npcsh-1.1.23.dist-info}/WHEEL +0 -0
  170. {npcsh-1.1.22.dist-info → npcsh-1.1.23.dist-info}/entry_points.txt +0 -0
  171. {npcsh-1.1.22.dist-info → npcsh-1.1.23.dist-info}/licenses/LICENSE +0 -0
  172. {npcsh-1.1.22.dist-info → npcsh-1.1.23.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- jinx_name: config_tui
1
+ jinx_name: config
2
2
  description: Interactive TUI editor for npcsh configuration (~/.npcshrc)
3
3
  interactive: true
4
4
  inputs: []
@@ -1,5 +1,5 @@
1
1
  jinx_name: convene
2
- description: Multi-NPC structured discussion with live TUI showing trains of thought
2
+ description: Start a group discussion between multiple NPCs. ONLY use for complex questions that need multiple perspectives. Never use for simple factual questions.
3
3
  interactive: true
4
4
  inputs:
5
5
  - topic: ""
@@ -23,12 +23,47 @@ steps:
23
23
 
24
24
  from npcpy.llm_funcs import get_llm_response
25
25
 
26
+ # Helper to log jinx executions to DB
27
+ def _log_jinx(trigger_id, npc_name, inputs, output, status="success", error_msg=None):
28
+ try:
29
+ if state and hasattr(state, 'command_history') and state.command_history is not None and hasattr(state.command_history, 'save_jinx_execution'):
30
+ _conv_id = getattr(state, 'conversation_id', None) or ''
31
+ state.command_history.save_jinx_execution(
32
+ triggering_message_id=f"{_conv_id}-{trigger_id}",
33
+ conversation_id=_conv_id,
34
+ npc_name=npc_name,
35
+ jinx_name="convene",
36
+ jinx_inputs=inputs,
37
+ jinx_output=str(output) if output else "",
38
+ status=status,
39
+ team_name=state.team.name if state and hasattr(state, 'team') and state.team else None,
40
+ error_message=error_msg,
41
+ )
42
+ except Exception:
43
+ pass
44
+
26
45
  npc = context.get('npc')
27
46
  team = context.get('team')
28
47
  messages = context.get('messages', [])
29
48
 
30
- model = context.get('model') or (npc.model if npc and hasattr(npc, 'model') else None)
31
- provider = context.get('provider') or (npc.provider if npc and hasattr(npc, 'provider') else None)
49
+ # Resolve model/provider: context NPC state env defaults
50
+ model = context.get('model') or (npc.model if npc and hasattr(npc, 'model') and npc.model else None)
51
+ if not model:
52
+ try:
53
+ model = state.chat_model if state and hasattr(state, 'chat_model') else None
54
+ except:
55
+ model = None
56
+ if not model:
57
+ model = os.environ.get('NPCSH_CHAT_MODEL', 'llama3.2')
58
+
59
+ provider = context.get('provider') or (npc.provider if npc and hasattr(npc, 'provider') and npc.provider else None)
60
+ if not provider:
61
+ try:
62
+ provider = state.chat_provider if state and hasattr(state, 'chat_provider') else None
63
+ except:
64
+ provider = None
65
+ if not provider:
66
+ provider = os.environ.get('NPCSH_CHAT_PROVIDER', 'ollama')
32
67
 
33
68
  topic = context.get('topic', '')
34
69
  npcs_str = context.get('npcs', 'alicanto,corca,guac')
@@ -104,6 +139,9 @@ steps:
104
139
  npc=participant.get('npc') or npc, temperature=0.7)
105
140
  contribution = str(resp.get('response', ''))
106
141
  print(contribution)
142
+ _log_jinx(f"convene-round-{round_num}-{name}", name,
143
+ {"prompt": prompt, "type": "main", "round": round_num},
144
+ contribution)
107
145
  entry = {'round': round_num, 'speaker': name, 'contribution': contribution}
108
146
  round_contributions.append(entry)
109
147
  discussion_log.append(entry)
@@ -124,6 +162,9 @@ steps:
124
162
  npc=fp.get('npc') or npc, temperature=0.7)
125
163
  fcontrib = str(fresp.get('response', ''))
126
164
  print(f" {fcontrib}")
165
+ _log_jinx(f"convene-round-{round_num}-{fn}-followup", fn,
166
+ {"prompt": fp_prompt, "type": "followup", "round": round_num, "responding_to": name},
167
+ fcontrib)
127
168
  discussion_log.append({'round': round_num, 'speaker': fn, 'contribution': fcontrib, 'type': 'followup'})
128
169
 
129
170
  if random.random() < 0.6:
@@ -141,6 +182,9 @@ steps:
141
182
  npc=rp.get('npc') or npc, temperature=0.7)
142
183
  ccontrib = str(cresp.get('response', ''))
143
184
  print(f" {ccontrib}")
185
+ _log_jinx(f"convene-round-{round_num}-{rn}-counter", rn,
186
+ {"prompt": cp, "type": "counter", "round": round_num, "responding_to": fn},
187
+ ccontrib)
144
188
  discussion_log.append({'round': round_num, 'speaker': rn, 'contribution': ccontrib, 'type': 'counter'})
145
189
 
146
190
  print(colored(f"\n{'='*60}", "green"))
@@ -162,6 +206,10 @@ steps:
162
206
  sresp = get_llm_response(synth_prompt, model=model, provider=provider, npc=npc, temperature=0.4)
163
207
  synthesis = str(sresp.get('response', ''))
164
208
  print(synthesis)
209
+ _log_jinx(f"convene-synthesis", npc.name if npc and hasattr(npc, 'name') else "convener",
210
+ {"prompt": synth_prompt, "type": "synthesis", "topic": topic,
211
+ "participants": [n.strip() for n in npcs_str.split(',')], "rounds": num_rounds},
212
+ synthesis)
165
213
 
166
214
  context['output'] = synthesis
167
215
  context['messages'] = messages
@@ -287,8 +335,14 @@ steps:
287
335
  resp = get_llm_response(prompt, model=model, provider=provider,
288
336
  npc=participant.get('npc') or npc, temperature=0.7)
289
337
  contribution = str(resp.get('response', ''))
338
+ _log_jinx(f"convene-round-{round_num}-{name}", name,
339
+ {"prompt": prompt, "type": "main", "round": round_num},
340
+ contribution)
290
341
  except Exception as e:
291
342
  contribution = f'(Error: {e})'
343
+ _log_jinx(f"convene-round-{round_num}-{name}", name,
344
+ {"prompt": prompt, "type": "main", "round": round_num},
345
+ contribution, status="error", error_msg=str(e))
292
346
 
293
347
  # Add contribution lines
294
348
  for line in wrap(contribution, 70):
@@ -323,8 +377,14 @@ steps:
323
377
  fresp = get_llm_response(followup_prompt, model=model, provider=provider,
324
378
  npc=followup_p.get('npc') or npc, temperature=0.7)
325
379
  fcontrib = str(fresp.get('response', ''))
380
+ _log_jinx(f"convene-round-{round_num}-{fn}-followup", fn,
381
+ {"prompt": followup_prompt, "type": "followup", "round": round_num, "responding_to": name},
382
+ fcontrib)
326
383
  except Exception as e:
327
384
  fcontrib = f'(Error: {e})'
385
+ _log_jinx(f"convene-round-{round_num}-{fn}-followup", fn,
386
+ {"prompt": followup_prompt, "type": "followup", "round": round_num, "responding_to": name},
387
+ fcontrib, status="error", error_msg=str(e))
328
388
 
329
389
  for line in wrap(fcontrib, 66):
330
390
  ui.display_lines.append(f' {line}')
@@ -359,8 +419,14 @@ steps:
359
419
  cresp = get_llm_response(counter_prompt, model=model, provider=provider,
360
420
  npc=resp_p.get('npc') or npc, temperature=0.7)
361
421
  ccontrib = str(cresp.get('response', ''))
422
+ _log_jinx(f"convene-round-{round_num}-{rn}-counter", rn,
423
+ {"prompt": counter_prompt, "type": "counter", "round": round_num, "responding_to": fn},
424
+ ccontrib)
362
425
  except Exception as e:
363
426
  ccontrib = f'(Error: {e})'
427
+ _log_jinx(f"convene-round-{round_num}-{rn}-counter", rn,
428
+ {"prompt": counter_prompt, "type": "counter", "round": round_num, "responding_to": fn},
429
+ ccontrib, status="error", error_msg=str(e))
364
430
 
365
431
  for line in wrap(ccontrib, 66):
366
432
  ui.display_lines.append(f' {line}')
@@ -397,8 +463,15 @@ steps:
397
463
  try:
398
464
  sresp = get_llm_response(synth_prompt, model=model, provider=provider, npc=npc, temperature=0.4)
399
465
  ui.synthesis = str(sresp.get('response', ''))
466
+ _log_jinx(f"convene-synthesis", npc.name if npc and hasattr(npc, 'name') else "convener",
467
+ {"prompt": synth_prompt, "type": "synthesis", "topic": topic,
468
+ "participants": npc_names, "rounds": num_rounds},
469
+ ui.synthesis)
400
470
  except Exception as e:
401
471
  ui.synthesis = f'Synthesis error: {e}'
472
+ _log_jinx(f"convene-synthesis", npc.name if npc and hasattr(npc, 'name') else "convener",
473
+ {"type": "synthesis", "topic": topic},
474
+ ui.synthesis, status="error", error_msg=str(e))
402
475
 
403
476
  for line in wrap(ui.synthesis, 70):
404
477
  ui.display_lines.append(f' {line}')