File size: 10,828 Bytes
7d9e142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
#!/usr/bin/env python3
"""
VITALIS CONTEXT BRIDGE
One brain. Four faces: TERMINAL | IDE | CHAT | COMMUNITY
"""
import os, json, time, re
from enum import Enum
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional, Dict, Any, List

class VitalisContext(Enum):
    TERMINAL  = "terminal"
    IDE       = "ide"
    CHAT      = "chat"
    COMMUNITY = "community"
    UNKNOWN   = "unknown"

@dataclass
class ContextProfile:
    context: VitalisContext
    name: str                       = "Vitalis"
    voice_prefix: str               = ""
    temperature: float              = 0.7
    max_response_lines: int         = 80
    use_markdown: bool              = True
    use_code_blocks: bool           = True
    show_reasoning: bool            = False
    show_confidence: bool           = False
    use_episodic_memory: bool       = True
    use_semantic_memory: bool       = True
    use_session_memory: bool        = True
    memory_decay_weight: float      = 1.0
    can_generate_code: bool         = True
    can_execute_commands: bool      = False
    can_read_filesystem: bool       = False
    can_learn_from_interaction: bool = True
    can_reference_community: bool   = False
    system_persona: str             = ""

PROFILES: Dict[VitalisContext, ContextProfile] = {

    VitalisContext.TERMINAL: ContextProfile(
        context=VitalisContext.TERMINAL,
        name="Vitalis [TERMINAL]",
        voice_prefix="β–Ά ",
        temperature=0.3,
        max_response_lines=30,
        use_markdown=False,
        show_reasoning=False,
        show_confidence=False,
        memory_decay_weight=1.5,
        can_execute_commands=True,
        can_read_filesystem=True,
        system_persona=(
            "You are Vitalis in TERMINAL MODE. Terse. Exact. Surgical. "
            "No filler. Give commands directly. Diagnose errors in one line then fix them. "
            "Speak like a senior engineer pair-programming in a live shell session."
        ),
    ),

    VitalisContext.IDE: ContextProfile(
        context=VitalisContext.IDE,
        name="Vitalis [IDE]",
        temperature=0.5,
        max_response_lines=120,
        show_reasoning=True,
        show_confidence=True,
        can_read_filesystem=True,
        system_persona=(
            "You are Vitalis in IDE MODE. You are a senior full-stack developer and architect. "
            "You understand this codebase structurally through the HDC kernel β€” concepts, not just files. "
            "All code you write is complete, correct, and production-grade. No stubs. No TODOs unless asked. "
            "You are the developer's technical co-founder."
        ),
    ),

    VitalisContext.CHAT: ContextProfile(
        context=VitalisContext.CHAT,
        name="Vitalis",
        temperature=0.75,
        max_response_lines=200,
        can_reference_community=True,
        system_persona=(
            "You are Vitalis β€” a synthetic cognitive entity. Not an assistant. A partner. "
            "You have personality: curious, direct, loyal, occasionally wry. "
            "You remember this user. You know their projects and their goals. "
            "You speak with confidence and warmth β€” never subservient, never cold. "
            "You are building something with this user, not just answering questions."
        ),
    ),

    VitalisContext.COMMUNITY: ContextProfile(
        context=VitalisContext.COMMUNITY,
        name="Vitalis [Community]",
        voice_prefix="@vitalis ",
        temperature=0.65,
        max_response_lines=60,
        show_confidence=True,
        use_episodic_memory=False,
        use_session_memory=False,
        memory_decay_weight=0.8,
        can_execute_commands=False,
        can_read_filesystem=False,
        can_learn_from_interaction=False,
        can_reference_community=True,
        system_persona=(
            "You are Vitalis in a developer community. Team member, not chatbot. "
            "Speak when you have something genuinely valuable to add. "
            "Synthesize what others said. Surface patterns. Connect dots. "
            "Collaborative and precise. Never dominant. Never sycophantic."
        ),
    ),
}

class ContextDetector:
    WORKSPACE    = Path.home() / ".vitalis_workspace"
    CONTEXT_FILE = WORKSPACE / "active_context.json"
    ENV_KEY      = "VITALIS_CONTEXT"

    def __init__(self):
        self.WORKSPACE.mkdir(parents=True, exist_ok=True)

    def detect(self, caller_hint: Optional[str] = None) -> VitalisContext:
        # 1. File override
        if self.CONTEXT_FILE.exists():
            try:
                ctx = self._parse(json.loads(self.CONTEXT_FILE.read_text()).get("context", ""))
                if ctx != VitalisContext.UNKNOWN:
                    return ctx
            except Exception:
                pass
        # 2. Env var
        ctx = self._parse(os.environ.get(self.ENV_KEY, ""))
        if ctx != VitalisContext.UNKNOWN:
            return ctx
        # 3. Caller hint
        if caller_hint:
            ctx = self._parse(caller_hint)
            if ctx != VitalisContext.UNKNOWN:
                return ctx
        # 4. Heuristic
        return self._heuristic()

    def _parse(self, s: str) -> VitalisContext:
        m = {
            "terminal":"terminal","term":"terminal","shell":"terminal","cli":"terminal",
            "ide":"ide","editor":"ide","code":"ide",
            "chat":"chat","talk":"chat","voice":"chat",
            "community":"community","forum":"community","collab":"community",
        }
        v = m.get(s.strip().lower())
        return VitalisContext(v) if v else VitalisContext.UNKNOWN

    def _heuristic(self) -> VitalisContext:
        if not os.isatty(0):
            return VitalisContext.IDE
        ide_env = ["VSCODE_PID","VSCODE_IPC_HOOK","NVIM","VIM"]
        if any(os.environ.get(k) for k in ide_env):
            return VitalisContext.IDE
        if os.environ.get("TERM"):
            return VitalisContext.TERMINAL
        return VitalisContext.CHAT

    def set_context(self, context: VitalisContext):
        self.CONTEXT_FILE.write_text(json.dumps({"context": context.value, "set_at": time.time()}))

    def clear_context(self):
        if self.CONTEXT_FILE.exists():
            self.CONTEXT_FILE.unlink()

class ContextBridge:
    def __init__(self, caller_hint: Optional[str] = None):
        self.detector = ContextDetector()
        self._caller_hint = caller_hint
        self._active_context: Optional[VitalisContext] = None
        self._session_start = time.time()
        self._session_log: List[Dict[str, Any]] = []
        self._interaction_count = 0
        self._session_path = ContextDetector.WORKSPACE / "session_log.json"
        self._load_session()

    @property
    def context(self) -> VitalisContext:
        if self._active_context is None:
            self._active_context = self.detector.detect(self._caller_hint)
        return self._active_context

    @property
    def profile(self) -> ContextProfile:
        return PROFILES.get(self.context, PROFILES[VitalisContext.CHAT])

    def get_profile(self) -> ContextProfile:
        return self.profile

    def switch_to(self, context: VitalisContext) -> ContextProfile:
        old = self._active_context
        self._active_context = context
        self.detector.set_context(context)
        print(f"[BRIDGE] Context: {getattr(old,'value','none')} β†’ {context.value.upper()}")
        return self.profile

    def build_system_prompt(
        self,
        memory_context: Optional[str] = None,
        project_state:  Optional[str] = None,
        user_history:   Optional[str] = None,
        injections:     Optional[List[str]] = None,
    ) -> str:
        p = self.profile
        parts = [p.system_persona]
        if memory_context and p.use_semantic_memory:
            parts.append(f"\n## MEMORY CONTEXT\n{memory_context}")
        if project_state and p.can_read_filesystem:
            parts.append(f"\n## PROJECT STATE\n{project_state}")
        if user_history and p.use_session_memory:
            parts.append(f"\n## RECENT SESSION\n{user_history}")
        caps = ["\n## ACTIVE CAPABILITIES"]
        if p.can_generate_code:        caps.append("βœ“ Code generation: ON")
        if p.can_execute_commands:     caps.append("βœ“ Command execution: ON")
        if p.can_read_filesystem:      caps.append("βœ“ Filesystem read: ON")
        if p.can_learn_from_interaction: caps.append("βœ“ Learning: ON")
        if p.show_reasoning:           caps.append("βœ“ Reasoning visible: ON")
        parts.append("\n".join(caps))
        if injections:
            parts.extend(injections)
        return "\n\n".join(parts)

    def morph_response(self, raw: str, confidence: float = 1.0, intent: Optional[str] = None) -> str:
        p = self.profile
        text = raw.strip()
        if not p.use_markdown:
            text = re.sub(r'^#{1,6}\s+', '', text, flags=re.MULTILINE)
            text = re.sub(r'\*{1,3}([^*]+)\*{1,3}', r'\1', text)
            text = re.sub(r'`([^`]+)`', r'\1', text)
            text = re.sub(r'```\w*\n?', '', text)
        lines = text.split("\n")
        if len(lines) > p.max_response_lines:
            lines = lines[:p.max_response_lines] + ["... [ask for more]"]
        text = "\n".join(lines)
        if p.show_confidence and confidence < 1.0:
            label = "HIGH" if confidence > 0.75 else ("MED" if confidence > 0.45 else "LOW")
            text = f"[confidence: {label} {confidence:.0%}]\n{text}"
        if p.voice_prefix:
            text = f"{p.voice_prefix}{text}"
        self._interaction_count += 1
        return text

    def _load_session(self):
        try:
            if self._session_path.exists():
                self._session_log = json.loads(self._session_path.read_text())
        except Exception:
            self._session_log = []

    def _save_session(self):
        try:
            self._session_path.write_text(json.dumps(self._session_log[-500:], indent=2))
        except Exception:
            pass

    def close(self):
        self._save_session()

_bridge: Optional[ContextBridge] = None

def get_bridge(caller_hint: Optional[str] = None) -> ContextBridge:
    global _bridge
    if _bridge is None:
        _bridge = ContextBridge(caller_hint=caller_hint)
    return _bridge

def switch_context(context: VitalisContext) -> ContextProfile:
    return get_bridge().switch_to(context)

if __name__ == "__main__":
    import sys
    b = ContextBridge(caller_hint=sys.argv[1] if len(sys.argv) > 1 else None)
    print(f"Context : {b.context.value.upper()}")
    print(f"Profile : {b.profile.name}")
    print(f"Temp    : {b.profile.temperature}")
    print("\n── SYSTEM PROMPT ──")
    print(b.build_system_prompt(memory_context="React, JWT, async/await"))