AQIT
0.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
ink_bridge.py
Go to the documentation of this file.
1
# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2
"""JSONL bridge for driving the Python chat agent from another process.
3
4
stdin (commands): {"type":"user","text":"..."} | {"type":"cancel"} | {"type":"exit"}
5
stdout (events): ready | token | tool.start | tool.result | turn.done | error | bye
6
"""
7
8
from
__future__
import
annotations
9
10
import
json
11
import
os
12
import
sys
13
import
threading
14
from
typing
import
Any
15
16
17
def
_emit
(event: dict[str, Any]) ->
None
:
18
sys.stdout.write(json.dumps(event, ensure_ascii=
False
) +
"\n"
)
19
sys.stdout.flush()
20
21
22
def
run_ink_chat_bridge
() -> None:
23
"""Session loop: load model once, then serve turns until exit/EOF."""
24
from
aquin.cli
import
_BASE_URL, _inject_session_mode
25
from
aquin.compute.model_loader
import
get_active_model_id, load_model, resolve_model_id
26
from
aquin.engine.agent
import
run_agent_turn
27
from
aquin.engine.local_server
import
start
as
_start_local_server
28
from
aquin.engine.main
import
_load_state, resolve_api_key
29
from
aquin.engine.session_memory_store
import
load_local_memory
30
from
aquin.session_mode
import
get_filtered_tool_schemas, mode_for_model_id, mode_label
31
32
active = (get_active_model_id()
or
""
).strip()
33
if
not
active:
34
_emit
({
35
"type"
:
"error"
,
36
"message"
:
"No model loaded. Run: aquin load model <id>"
,
37
"fatal"
:
True
,
38
})
39
_emit
({
"type"
:
"bye"
})
40
return
41
try
:
42
locked_model = resolve_model_id(active)
43
except
ValueError:
44
locked_model = active
45
46
state = _load_state()
47
api_key = state.get(
"api_key"
)
or
resolve_api_key()
48
if
not
api_key:
49
_emit
({
50
"type"
:
"error"
,
51
"message"
:
"Cloud session not configured for chat."
,
52
"fatal"
:
True
,
53
})
54
_emit
({
"type"
:
"bye"
})
55
return
56
57
base_url = (state.get(
"base_url"
)
or
os.environ.get(
"AQUIN_BASE_URL"
, _BASE_URL)).rstrip(
"/"
)
58
59
try
:
60
chat_mode = mode_for_model_id(locked_model)
61
if
not
get_filtered_tool_schemas(chat_mode):
62
_emit
({
63
"type"
:
"error"
,
64
"message"
:
"No tools available for this model mode. Run: aquin load model <id>"
,
65
"fatal"
:
True
,
66
})
67
_emit
({
"type"
:
"bye"
})
68
return
69
except
ValueError
as
exc:
70
_emit
({
"type"
:
"error"
,
"message"
: str(exc),
"fatal"
:
True
})
71
_emit
({
"type"
:
"bye"
})
72
return
73
74
session_state: dict = {
75
"memory"
: load_local_memory(
"local"
),
76
"activeModelId"
: locked_model,
77
"session_mode"
: chat_mode,
78
}
79
session_state = _inject_session_mode(session_state)
80
81
from
aquin.compute.loader_shim
import
apply
as
_shim_apply
82
83
_shim_apply()
84
try
:
85
load_model(locked_model)
86
except
Exception
as
exc:
87
_emit
({
"type"
:
"error"
,
"message"
: str(exc),
"fatal"
:
True
})
88
_emit
({
"type"
:
"bye"
})
89
return
90
91
_start_local_server()
92
93
_emit
({
94
"type"
:
"ready"
,
95
"model"
: locked_model,
96
"mode"
: chat_mode,
97
"mode_label"
: mode_label(chat_mode),
98
})
99
100
cancel_event = threading.Event()
101
turn_lock = threading.Lock()
102
103
def
_run_turn(user_text: str) ->
None
:
104
cancel_event.clear()
105
106
def
_on_token(piece: str) ->
None
:
107
if
cancel_event.is_set():
108
raise
KeyboardInterrupt()
109
_emit
({
"type"
:
"token"
,
"text"
: piece})
110
111
def
_on_tool_start(name: str, tool_args: dict) ->
None
:
112
if
cancel_event.is_set():
113
raise
KeyboardInterrupt()
114
_emit
({
"type"
:
"tool.start"
,
"name"
: name,
"args"
: tool_args
or
{}})
115
116
def
_on_tool_result(name: str, result: Any, is_error: bool) ->
None
:
117
_ = result
118
_emit
({
"type"
:
"tool.result"
,
"name"
: name,
"error"
: bool(is_error)})
119
120
try
:
121
run_agent_turn(
122
session_id=
""
,
123
user_message=user_text,
124
state=session_state,
125
api_key=api_key,
126
base_url=base_url,
127
on_token=_on_token,
128
on_tool_start=_on_tool_start,
129
on_tool_result=_on_tool_result,
130
)
131
if
cancel_event.is_set():
132
_emit
({
"type"
:
"error"
,
"message"
:
"Cancelled."
,
"fatal"
:
False
})
133
else
:
134
_emit
({
"type"
:
"turn.done"
})
135
except
KeyboardInterrupt:
136
_emit
({
"type"
:
"error"
,
"message"
:
"Cancelled."
,
"fatal"
:
False
})
137
_emit
({
"type"
:
"turn.done"
})
138
except
Exception
as
exc:
139
msg = str(exc)
140
if
"401"
in
msg
or
"403"
in
msg:
141
msg =
"Auth error. Set required env credentials."
142
elif
"connect"
in
msg.lower()
or
"connection"
in
msg.lower()
or
"network"
in
msg.lower():
143
msg =
"Could not reach Aquin. Check your internet connection."
144
else
:
145
msg =
"Something went wrong. Try again."
146
_emit
({
"type"
:
"error"
,
"message"
: msg,
"fatal"
:
False
})
147
_emit
({
"type"
:
"turn.done"
})
148
149
for
line
in
sys.stdin:
150
line = line.strip()
151
if
not
line:
152
continue
153
try
:
154
cmd = json.loads(line)
155
except
json.JSONDecodeError:
156
_emit
({
"type"
:
"error"
,
"message"
:
"bad command JSON"
,
"fatal"
:
False
})
157
continue
158
159
kind = cmd.get(
"type"
)
160
if
kind ==
"exit"
:
161
break
162
if
kind ==
"cancel"
:
163
cancel_event.set()
164
continue
165
if
kind !=
"user"
:
166
_emit
({
"type"
:
"error"
,
"message"
: f
"unknown command: {kind}"
,
"fatal"
:
False
})
167
continue
168
169
text = str(cmd.get(
"text"
)
or
""
).strip()
170
if
not
text:
171
continue
172
173
if
not
turn_lock.acquire(blocking=
False
):
174
_emit
({
"type"
:
"error"
,
"message"
:
"Turn already in progress."
,
"fatal"
:
False
})
175
continue
176
177
try
:
178
_run_turn(text)
179
finally
:
180
turn_lock.release()
181
182
_emit
({
"type"
:
"bye"
})
aquin.cli
Definition
cli.py:1
aquin.compute.loader_shim
Definition
loader_shim.py:1
aquin.compute.model_loader
Definition
model_loader.py:1
aquin.engine.agent
Definition
agent.py:1
aquin.engine.local_server
Definition
local_server.py:1
aquin.engine.main
Definition
main.py:1
aquin.engine.session_memory_store
Definition
session_memory_store.py:1
aquin.session_mode
Definition
session_mode.py:1
aquin.tui.ink_bridge._emit
None _emit(dict[str, Any] event)
Definition
ink_bridge.py:21
aquin.tui.ink_bridge.run_ink_chat_bridge
None run_ink_chat_bridge()
Definition
ink_bridge.py:26
aquin
tui
ink_bridge.py
AQIT · Aquin Labs Private Limited · Apache 2.0 · Generated by
1.18.0