@oracle-agent/oracle 0.9.0 → 0.9.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oracle-agent/oracle",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Oracle: prepare-only multichain agent control plane. Policy-bounded intents for a user-signed wallet. Self-custody by default — the public package never takes your key. Built for Hermes; no model key required.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -10,8 +10,6 @@ import sys
10
10
 
11
11
 
12
12
  WORDMARK = (
13
- " ████ ",
14
- " ░░███ ",
15
13
  " ██████ ████████ ██████ ██████ ░███ ██████ ",
16
14
  " ███░░███░░███░░███ ░░░░░███ ███░░███ ░███ ███░░███",
17
15
  "░███ ░███ ░███ ░░░ ███████ ░███ ░░░ ░███ ░███████ ",
@@ -109,8 +107,10 @@ def patch_cli(module):
109
107
 
110
108
  def show_banner(self):
111
109
  from rich.align import Align
110
+ from rich.console import Group
112
111
  from rich.panel import Panel
113
112
  from rich.text import Text
113
+ from rich import box
114
114
 
115
115
  self.console.clear()
116
116
  width = shutil.get_terminal_size((100, 28)).columns
@@ -122,8 +122,6 @@ def patch_cli(module):
122
122
  "#ACDEEF",
123
123
  "#A5D9EB",
124
124
  "#9FCBDD",
125
- "#9FCBDD",
126
- "#ACDEEF",
127
125
  "#B8F0FF",
128
126
  )
129
127
  for index, line in enumerate(WORDMARK):
@@ -137,14 +135,16 @@ def patch_cli(module):
137
135
  body.append(" / ", style="#52606D")
138
136
  model = str(getattr(self, "model", "") or "choose model")
139
137
  body.append(model, style="#91A2B1")
140
- body.append("\n\n/model /chain /setup", style="#60717F")
141
138
 
142
- panel_width = min(max(66, 66 if width >= 72 else 34), max(width - 4, 34))
139
+ panel_width = max(36, min(width - 4, 76))
143
140
  panel = Panel(
144
- Align.center(body),
141
+ Group(Align.center(body)),
145
142
  width=panel_width,
146
- padding=(0, 2),
147
- border_style="#455867",
143
+ padding=(1, 2),
144
+ border_style="#3B4A56",
145
+ box=box.ROUNDED,
146
+ subtitle="[dim #6F7F8D]/model /chain /setup[/]",
147
+ subtitle_align="center",
148
148
  )
149
149
  self.console.print(Align.center(panel))
150
150
  self.console.print()
@@ -166,7 +166,81 @@ def patch_cli(module):
166
166
  return [("class:prompt-working", "working ")]
167
167
  if getattr(self, "_agent_running", False):
168
168
  return [("class:prompt-working", "thinking ")]
169
- return [("class:prompt", "› ")]
169
+ return [("class:prompt", " Ask Oracle › ")]
170
+
171
+ def status_fragments(self):
172
+ if not getattr(self, "_status_bar_visible", True) or getattr(self, "_model_picker_state", None):
173
+ return []
174
+ try:
175
+ snapshot = self._get_status_bar_snapshot()
176
+ width = self._get_tui_terminal_width()
177
+ model = snapshot.get("model_short") or "model"
178
+ percent = snapshot.get("context_percent") or 0
179
+ context_tokens = snapshot.get("context_tokens") or 0
180
+ context_length = snapshot.get("context_length") or 0
181
+ context_bar = self._build_context_bar(percent, width=8)
182
+
183
+ def compact_tokens(value):
184
+ if value >= 1_000_000:
185
+ return f"{value / 1_000_000:.1f}M"
186
+ if value >= 1_000:
187
+ return f"{value / 1_000:.0f}K"
188
+ return str(value)
189
+
190
+ usage = f"{compact_tokens(context_tokens)}/{compact_tokens(context_length)} " if context_length else ""
191
+ reasoning_config = getattr(self, "reasoning_config", None) or {}
192
+ if reasoning_config.get("enabled") is False:
193
+ effort = "none"
194
+ else:
195
+ effort = reasoning_config.get("effort") or "default"
196
+ thinking = snapshot.get("prompt_elapsed") or "0s"
197
+ thinking = thinking.replace("⏱ ", "").replace("⏲ ", "")
198
+
199
+ if width < 48:
200
+ short_bar = self._build_context_bar(percent, width=4)
201
+ return [
202
+ ("class:status-bar", " "),
203
+ ("class:status-bar-context", f"ctx {short_bar} {percent}%"),
204
+ ("class:status-bar-dim", " / "),
205
+ ("class:status-bar-effort", effort),
206
+ ("class:status-bar-dim", " / "),
207
+ ("class:status-bar-time", f"{thinking} "),
208
+ ]
209
+ if width < 70:
210
+ short_bar = self._build_context_bar(percent, width=4)
211
+ return [
212
+ ("class:status-bar", " "),
213
+ ("class:status-bar-context", f"ctx {short_bar} {percent}%"),
214
+ ("class:status-bar-dim", " / "),
215
+ ("class:status-bar-effort", f"effort {effort}"),
216
+ ("class:status-bar-dim", " / "),
217
+ ("class:status-bar-time", f"think {thinking} "),
218
+ ]
219
+ if width < 92:
220
+ return [
221
+ ("class:status-bar", " "),
222
+ ("class:status-bar-strong", model),
223
+ ("class:status-bar-dim", " / "),
224
+ ("class:status-bar-context", f"ctx {context_bar} {usage}{percent}%"),
225
+ ("class:status-bar-dim", " / "),
226
+ ("class:status-bar-effort", f"effort {effort}"),
227
+ ("class:status-bar-dim", " / "),
228
+ ("class:status-bar-time", f"think {thinking} "),
229
+ ]
230
+ return [
231
+ ("class:status-bar", " "),
232
+ ("class:status-bar-brand", "oracle"),
233
+ ("class:status-bar-dim", " / "),
234
+ ("class:status-bar-strong", model),
235
+ ("class:status-bar-dim", " / "),
236
+ ("class:status-bar-context", f"ctx {context_bar} {usage}{percent}%"),
237
+ ("class:status-bar-dim", " / "),
238
+ ("class:status-bar-effort", f"effort {effort}"),
239
+ ("class:status-bar-dim", " / "),
240
+ ("class:status-bar-time", f"think {thinking} "),
241
+ ]
242
+ except Exception:
243
+ return [("class:status-bar-brand", " oracle ")]
170
244
 
171
245
  def layout_children(
172
246
  self,
@@ -187,7 +261,7 @@ def patch_cli(module):
187
261
  voice_status_bar,
188
262
  completions_menu,
189
263
  ):
190
- from prompt_toolkit.layout.containers import HSplit, Window
264
+ from prompt_toolkit.layout.containers import HSplit, VSplit, Window
191
265
  from prompt_toolkit.widgets import Frame
192
266
  from prompt_toolkit.widgets.base import Border
193
267
 
@@ -196,9 +270,15 @@ def patch_cli(module):
196
270
  Border.BOTTOM_LEFT = "╰"
197
271
  Border.BOTTOM_RIGHT = "╯"
198
272
 
199
- composer = Frame(
200
- HSplit([item for item in (image_bar, input_area) if item is not None]),
201
- style="class:oracle-composer",
273
+ composer = VSplit(
274
+ [
275
+ Window(width=1),
276
+ Frame(
277
+ HSplit([item for item in (image_bar, input_area) if item is not None]),
278
+ style="class:oracle-composer",
279
+ ),
280
+ Window(width=1),
281
+ ]
202
282
  )
203
283
  return [
204
284
  item
@@ -215,6 +295,7 @@ def patch_cli(module):
215
295
  composer,
216
296
  completions_menu,
217
297
  voice_status_bar,
298
+ status_bar,
218
299
  )
219
300
  if item is not None
220
301
  ]
@@ -230,6 +311,13 @@ def patch_cli(module):
230
311
  "input-area": "bg:#0B0E11 #EAF2F8",
231
312
  "prompt": "bold #B8F0FF",
232
313
  "prompt-working": "bold #91C2D7",
314
+ "status-bar": "bg:#11161B #91A2B1",
315
+ "status-bar-brand": "bg:#11161B bold #B8F0FF",
316
+ "status-bar-strong": "bg:#11161B #EAF2F8",
317
+ "status-bar-context": "bg:#11161B #A5D9EB",
318
+ "status-bar-effort": "bg:#11161B #C5B8FF",
319
+ "status-bar-time": "bg:#11161B #91A2B1",
320
+ "status-bar-dim": "bg:#11161B #60717F",
233
321
  }
234
322
  )
235
323
  return style
@@ -247,6 +335,7 @@ def patch_cli(module):
247
335
 
248
336
  setattr(cls, "show_banner", show_banner)
249
337
  setattr(cls, "_get_tui_prompt_fragments", prompt_fragments)
338
+ setattr(cls, "_get_status_bar_fragments", status_fragments)
250
339
  setattr(cls, "_build_tui_layout_children", layout_children)
251
340
  setattr(cls, "_build_tui_style_dict", build_style)
252
341
  setattr(cls, "process_command", process_command)