Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-25 08:29:12

0001 #!/usr/bin/env python3
0002 """
0003 Load AI dialogue history at Claude Code session start.
0004 
0005 Called by Claude Code SessionStart hook to inject recent conversation
0006 context into the new session.
0007 
0008 Environment:
0009     SWF_DIALOGUE_TURNS: Number of turns to load (default: 0 = disabled)
0010     SWF_MONITOR_HTTP_URL: Monitor API URL (default: http://pandaserver02.sdcc.bnl.gov/swf-monitor)
0011 
0012 Output:
0013     Prints formatted dialogue history to stdout (injected into Claude's context)
0014 """
0015 
0016 import json
0017 import os
0018 import sys
0019 import getpass
0020 from pathlib import Path
0021 from typing import Optional
0022 
0023 
0024 def get_turns_setting():
0025     # type: () -> int
0026     try:
0027         return int(os.getenv('SWF_DIALOGUE_TURNS', '0'))
0028     except ValueError:
0029         return 0
0030 
0031 
0032 def load_sysprompt(cwd):
0033     # type: (str) -> Optional[str]
0034     sysprompt_path = Path(cwd) / 'SYSPROMPT.md'
0035     if sysprompt_path.exists():
0036         try:
0037             return sysprompt_path.read_text()
0038         except Exception:
0039             pass
0040     return None
0041 
0042 
0043 def load_dialogue_via_api(username, turns, namespace=None):
0044     # type: (str, int, str) -> list
0045     import urllib.request
0046     import urllib.error
0047 
0048     base_url = os.getenv('SWF_MONITOR_HTTP_URL', 'http://pandaserver02.sdcc.bnl.gov/swf-monitor')
0049     params = "username={}&turns={}".format(username, turns)
0050     if namespace:
0051         params += "&namespace={}".format(namespace)
0052     url = "{}/api/ai-memory/?{}".format(base_url.rstrip('/'), params)
0053 
0054     try:
0055         req = urllib.request.Request(url, method='GET')
0056         with urllib.request.urlopen(req, timeout=5) as resp:
0057             if resp.status == 200:
0058                 data = json.loads(resp.read().decode('utf-8'))
0059                 return data.get('items', [])
0060     except (urllib.error.URLError, urllib.error.HTTPError, OSError, json.JSONDecodeError):
0061         pass
0062 
0063     return []
0064 
0065 
0066 def format_dialogue(messages):
0067     # type: (list) -> str
0068     if not messages:
0069         return ""
0070 
0071     lines = ["## Recent Conversation History", ""]
0072     for msg in messages:
0073         role = msg.get('role', 'unknown').upper()
0074         content = msg.get('content', '')
0075         if len(content) > 2000:
0076             content = content[:2000] + "... [truncated]"
0077         lines.append("**{}:** {}".format(role, content))
0078         lines.append("")
0079 
0080     return "\n".join(lines)
0081 
0082 
0083 def get_namespace(cwd):
0084     # type: (str) -> Optional[str]
0085     testbed_toml = os.path.join(cwd, 'workflows', 'testbed.toml')
0086     if not os.path.exists(testbed_toml):
0087         return None
0088     try:
0089         try:
0090             import tomllib
0091             with open(testbed_toml, 'rb') as f:
0092                 data = tomllib.load(f)
0093             return data.get('testbed', {}).get('namespace')
0094         except ImportError:
0095             with open(testbed_toml, 'r') as f:
0096                 for line in f:
0097                     line = line.strip()
0098                     if line.startswith('namespace'):
0099                         parts = line.split('=', 1)
0100                         if len(parts) == 2:
0101                             return parts[1].strip().strip('"').strip("'")
0102     except Exception:
0103         pass
0104     return None
0105 
0106 
0107 def main():
0108     try:
0109         hook_input = json.load(sys.stdin)
0110     except json.JSONDecodeError:
0111         sys.exit(0)
0112 
0113     source = hook_input.get('source', '')
0114     if source not in ('startup', 'resume'):
0115         sys.exit(0)
0116 
0117     cwd = hook_input.get('cwd', os.getcwd())
0118     username = getpass.getuser()
0119     namespace = get_namespace(cwd)
0120 
0121     output_parts = []
0122 
0123     sysprompt = load_sysprompt(cwd)
0124     if sysprompt:
0125         output_parts.append(sysprompt)
0126 
0127     turns = get_turns_setting()
0128     if turns > 0:
0129         messages = load_dialogue_via_api(username, turns, namespace)
0130         if messages:
0131             dialogue = format_dialogue(messages)
0132             if dialogue:
0133                 output_parts.append(dialogue)
0134 
0135     if output_parts:
0136         print("\n\n".join(output_parts))
0137 
0138     sys.exit(0)
0139 
0140 
0141 if __name__ == '__main__':
0142     main()