agentix-cli 0.115.0 → 0.116.0
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/apps/mac-voice/Sources/AgentXVoice/AnswerView.swift +24 -2
- package/apps/mac-voice/Sources/AgentXVoice/ListenAgain.swift +26 -0
- package/apps/mac-voice/Sources/AgentXVoice/main.swift +54 -0
- package/dist/{App-6OMMZW2M.js → App-7Z2PWARZ.js} +2 -2
- package/dist/{ChatApp-EDDROHNA.js → ChatApp-GFAIRLGZ.js} +2 -2
- package/dist/{agent-VPM3EEUB.js → agent-LXLZGVW3.js} +2 -2
- package/dist/{board-dashboard-4GQ7RTH3.js → board-dashboard-CPCSSVZE.js} +255 -224
- package/dist/board-dashboard-CPCSSVZE.js.map +1 -0
- package/dist/chunk-6LCP6SVR.js +482 -0
- package/dist/chunk-6LCP6SVR.js.map +1 -0
- package/dist/{chunk-MG5LRE5B.js → chunk-7IF3LXAU.js} +2 -2
- package/dist/{chunk-7T7IXLLA.js → chunk-AWQIUI7N.js} +2 -2
- package/dist/{chunk-5FY7PWXW.js → chunk-B65YTB3T.js} +2 -2
- package/dist/chunk-BRL3UPFW.js +2 -0
- package/dist/chunk-BRL3UPFW.js.map +1 -0
- package/dist/{chunk-EVXL6X2R.js → chunk-CCL73Z2P.js} +56 -56
- package/dist/{chunk-EVXL6X2R.js.map → chunk-CCL73Z2P.js.map} +1 -1
- package/dist/{chunk-ECBVOIIK.js → chunk-CKYSGX54.js} +171 -171
- package/dist/chunk-CKYSGX54.js.map +1 -0
- package/dist/chunk-DMHQIACQ.js +3 -0
- package/dist/chunk-DMHQIACQ.js.map +1 -0
- package/dist/{chunk-K3BG77KK.js → chunk-EKOVLUKH.js} +2 -2
- package/dist/{chunk-S4XSVAAG.js → chunk-ELWKTURG.js} +2 -2
- package/dist/chunk-EMGB23H5.js +3 -0
- package/dist/chunk-EMGB23H5.js.map +1 -0
- package/dist/{chunk-IGORU3XR.js → chunk-FBEMUCBO.js} +2 -2
- package/dist/{chunk-IGORU3XR.js.map → chunk-FBEMUCBO.js.map} +1 -1
- package/dist/chunk-GRMCAO3Q.js +2 -0
- package/dist/chunk-GRMCAO3Q.js.map +1 -0
- package/dist/{chunk-CJJULHPJ.js → chunk-HOY2GIKV.js} +4 -4
- package/dist/{chunk-YE4HKOS5.js → chunk-HSYNOMM2.js} +2 -2
- package/dist/{chunk-PITMPRVP.js → chunk-IEZ6OYFJ.js} +2 -2
- package/dist/{chunk-BXYKFWAI.js → chunk-J3SIOMDL.js} +2 -2
- package/dist/{chunk-PX2AOZ5G.js → chunk-JLCJVPRC.js} +2 -2
- package/dist/{chunk-QLB76BGE.js → chunk-KI4CIUVJ.js} +2 -2
- package/dist/{chunk-2NYP4OQU.js → chunk-LNY6N73E.js} +4 -4
- package/dist/{chunk-2NYP4OQU.js.map → chunk-LNY6N73E.js.map} +1 -1
- package/dist/{chunk-KTF4YF4M.js → chunk-R277UDDQ.js} +2 -2
- package/dist/{chunk-4STXRZZS.js → chunk-S56ZGAFM.js} +2 -2
- package/dist/{chunk-SDOSQ6TJ.js → chunk-UUMNP47Q.js} +2 -2
- package/dist/{chunk-UQX2HY5M.js → chunk-WRICEAR6.js} +2 -2
- package/dist/{chunk-J5TZ6QGD.js → chunk-Y3CZE54A.js} +2 -2
- package/dist/{chunk-BU4LE2RT.js → chunk-YMNQYODO.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-VUNPLVCG.js → client-CU5GNTKR.js} +2 -2
- package/dist/{config-HE2LGTTG.js → config-ITVBNUWW.js} +2 -2
- package/dist/config-mutator-5YRHHA2I.js +2 -0
- package/dist/doctor-MLD3XCYE.js +2 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{program-53CQJEUZ.js → program-IBOVOVZI.js} +191 -187
- package/dist/program-IBOVOVZI.js.map +1 -0
- package/dist/{promote-4PPJJ6AW.js → promote-JMJPWZI7.js} +2 -2
- package/dist/push-DID6RZYI.js +2 -0
- package/dist/push-bridge-IFUQLIMF.js +2 -0
- package/dist/push-store-L5QHMSST.js +2 -0
- package/dist/{query-ETDKC7WC.js → query-QGPVKGYY.js} +2 -2
- package/dist/{registry-AMETOJ3S.js → registry-PZNC5XYT.js} +2 -2
- package/dist/{request-planner-VFWWT5XR.js → request-planner-M4IKDZBU.js} +2 -2
- package/dist/{review-candidates-2PI4CGZO.js → review-candidates-6DNRBJZ6.js} +2 -2
- package/dist/routing-7NSB6O2S.js +2 -0
- package/dist/schedule-tool-ZP7H55EL.js +2 -0
- package/dist/scheduler-XV5UQQYH.js +2 -0
- package/dist/{seat-TVNR245I.js → seat-ZRCUQCUP.js} +2 -2
- package/dist/{select-KY7B4HAS.js → select-OLNLTEBR.js} +2 -2
- package/dist/{set-enabled-NEINY2I2.js → set-enabled-LG3ESZDC.js} +2 -2
- package/dist/token-store-AY6OBDVI.js +2 -0
- package/dist/token-store-AY6OBDVI.js.map +1 -0
- package/dist/{tool-MQQ2W5LJ.js → tool-RBXRPIBV.js} +2 -2
- package/dist/{tool-5JGMWH62.js → tool-S6U42ULD.js} +2 -2
- package/dist/wiki-XKQN5CWR.js +2 -0
- package/dist/wiki-XKQN5CWR.js.map +1 -0
- package/package.json +1 -1
- package/dist/board-dashboard-4GQ7RTH3.js.map +0 -1
- package/dist/chunk-2QSG53RN.js +0 -482
- package/dist/chunk-2QSG53RN.js.map +0 -1
- package/dist/chunk-ACFQBLPX.js +0 -3
- package/dist/chunk-ACFQBLPX.js.map +0 -1
- package/dist/chunk-ECBVOIIK.js.map +0 -1
- package/dist/config-mutator-22AVTST2.js +0 -2
- package/dist/doctor-6RDRST4G.js +0 -2
- package/dist/program-53CQJEUZ.js.map +0 -1
- package/dist/push-HEDA6P3B.js +0 -2
- package/dist/push-HEDA6P3B.js.map +0 -1
- package/dist/push-store-5VJ4FNI4.js +0 -2
- package/dist/routing-M7MDLD7Q.js +0 -2
- package/dist/schedule-tool-2EQ53IOQ.js +0 -2
- package/dist/scheduler-YGVINPZF.js +0 -2
- package/dist/token-store-YBSU2DTV.js +0 -2
- package/dist/wiki-COAUQ6TQ.js +0 -2
- /package/dist/{App-6OMMZW2M.js.map → App-7Z2PWARZ.js.map} +0 -0
- /package/dist/{ChatApp-EDDROHNA.js.map → ChatApp-GFAIRLGZ.js.map} +0 -0
- /package/dist/{agent-VPM3EEUB.js.map → agent-LXLZGVW3.js.map} +0 -0
- /package/dist/{chunk-MG5LRE5B.js.map → chunk-7IF3LXAU.js.map} +0 -0
- /package/dist/{chunk-7T7IXLLA.js.map → chunk-AWQIUI7N.js.map} +0 -0
- /package/dist/{chunk-5FY7PWXW.js.map → chunk-B65YTB3T.js.map} +0 -0
- /package/dist/{chunk-K3BG77KK.js.map → chunk-EKOVLUKH.js.map} +0 -0
- /package/dist/{chunk-S4XSVAAG.js.map → chunk-ELWKTURG.js.map} +0 -0
- /package/dist/{chunk-CJJULHPJ.js.map → chunk-HOY2GIKV.js.map} +0 -0
- /package/dist/{chunk-YE4HKOS5.js.map → chunk-HSYNOMM2.js.map} +0 -0
- /package/dist/{chunk-PITMPRVP.js.map → chunk-IEZ6OYFJ.js.map} +0 -0
- /package/dist/{chunk-BXYKFWAI.js.map → chunk-J3SIOMDL.js.map} +0 -0
- /package/dist/{chunk-PX2AOZ5G.js.map → chunk-JLCJVPRC.js.map} +0 -0
- /package/dist/{chunk-QLB76BGE.js.map → chunk-KI4CIUVJ.js.map} +0 -0
- /package/dist/{chunk-KTF4YF4M.js.map → chunk-R277UDDQ.js.map} +0 -0
- /package/dist/{chunk-4STXRZZS.js.map → chunk-S56ZGAFM.js.map} +0 -0
- /package/dist/{chunk-SDOSQ6TJ.js.map → chunk-UUMNP47Q.js.map} +0 -0
- /package/dist/{chunk-UQX2HY5M.js.map → chunk-WRICEAR6.js.map} +0 -0
- /package/dist/{chunk-J5TZ6QGD.js.map → chunk-Y3CZE54A.js.map} +0 -0
- /package/dist/{chunk-BU4LE2RT.js.map → chunk-YMNQYODO.js.map} +0 -0
- /package/dist/{client-VUNPLVCG.js.map → client-CU5GNTKR.js.map} +0 -0
- /package/dist/{config-HE2LGTTG.js.map → config-ITVBNUWW.js.map} +0 -0
- /package/dist/{config-mutator-22AVTST2.js.map → config-mutator-5YRHHA2I.js.map} +0 -0
- /package/dist/{doctor-6RDRST4G.js.map → doctor-MLD3XCYE.js.map} +0 -0
- /package/dist/{promote-4PPJJ6AW.js.map → promote-JMJPWZI7.js.map} +0 -0
- /package/dist/{push-store-5VJ4FNI4.js.map → push-DID6RZYI.js.map} +0 -0
- /package/dist/{query-ETDKC7WC.js.map → push-bridge-IFUQLIMF.js.map} +0 -0
- /package/dist/{registry-AMETOJ3S.js.map → push-store-L5QHMSST.js.map} +0 -0
- /package/dist/{routing-M7MDLD7Q.js.map → query-QGPVKGYY.js.map} +0 -0
- /package/dist/{schedule-tool-2EQ53IOQ.js.map → registry-PZNC5XYT.js.map} +0 -0
- /package/dist/{request-planner-VFWWT5XR.js.map → request-planner-M4IKDZBU.js.map} +0 -0
- /package/dist/{review-candidates-2PI4CGZO.js.map → review-candidates-6DNRBJZ6.js.map} +0 -0
- /package/dist/{scheduler-YGVINPZF.js.map → routing-7NSB6O2S.js.map} +0 -0
- /package/dist/{seat-TVNR245I.js.map → schedule-tool-ZP7H55EL.js.map} +0 -0
- /package/dist/{token-store-YBSU2DTV.js.map → scheduler-XV5UQQYH.js.map} +0 -0
- /package/dist/{wiki-COAUQ6TQ.js.map → seat-ZRCUQCUP.js.map} +0 -0
- /package/dist/{select-KY7B4HAS.js.map → select-OLNLTEBR.js.map} +0 -0
- /package/dist/{set-enabled-NEINY2I2.js.map → set-enabled-LG3ESZDC.js.map} +0 -0
- /package/dist/{tool-MQQ2W5LJ.js.map → tool-RBXRPIBV.js.map} +0 -0
- /package/dist/{tool-5JGMWH62.js.map → tool-S6U42ULD.js.map} +0 -0
|
@@ -31,6 +31,10 @@ final class AnswerView: NSView {
|
|
|
31
31
|
var onHeight: ((CGFloat) -> Void)?
|
|
32
32
|
/// "Open in chat". Set by the app.
|
|
33
33
|
var onOpenChat: (() -> Void)?
|
|
34
|
+
/// "Listen again" (#492): say the answer again, or stop saying it.
|
|
35
|
+
/// Set by the app, which owns the speaking.
|
|
36
|
+
var onListenAgain: (() -> Void)?
|
|
37
|
+
private var listenButton: NSButton?
|
|
34
38
|
|
|
35
39
|
private static let linkRow: CGFloat = 34
|
|
36
40
|
private static let imageHeight: CGFloat = 120
|
|
@@ -50,9 +54,14 @@ final class AnswerView: NSView {
|
|
|
50
54
|
links.edgeInsets = NSEdgeInsets(top: 4, left: 12, bottom: 8, right: 12)
|
|
51
55
|
addSubview(links)
|
|
52
56
|
|
|
53
|
-
// Copy and Open in chat, shown while the pointer is
|
|
57
|
+
// Listen again, Copy and Open in chat, shown while the pointer is
|
|
58
|
+
// over the answer.
|
|
54
59
|
actions.orientation = .horizontal
|
|
55
60
|
actions.spacing = 2
|
|
61
|
+
let idle = ListenAgain.look(replaying: false)
|
|
62
|
+
let listen = actionButton(idle.symbol, idle.label, #selector(listenAgain))
|
|
63
|
+
listenButton = listen
|
|
64
|
+
actions.addArrangedSubview(listen)
|
|
56
65
|
actions.addArrangedSubview(actionButton("doc.on.doc", "Copy the answer", #selector(copyAnswer)))
|
|
57
66
|
actions.addArrangedSubview(actionButton("bubble.left.and.bubble.right", "Open in chat", #selector(openChat)))
|
|
58
67
|
actions.isHidden = true
|
|
@@ -93,7 +102,8 @@ final class AnswerView: NSView {
|
|
|
93
102
|
thumb.frame = NSRect(x: 12, y: h - imgH - 10, width: w - 24, height: imgH)
|
|
94
103
|
web.frame = NSRect(x: 0, y: linkH, width: w, height: max(0, h - linkH - imgH - (imgH > 0 ? 16 : 0)))
|
|
95
104
|
links.frame = NSRect(x: 0, y: 0, width: w, height: linkH)
|
|
96
|
-
|
|
105
|
+
// Three 24-point buttons, 2 apart, with 3 points each side.
|
|
106
|
+
actions.frame = NSRect(x: w - 90, y: h - 32, width: 82, height: 26)
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
/// Does this turn have anything the spoken answer did not already
|
|
@@ -198,6 +208,18 @@ final class AnswerView: NSView {
|
|
|
198
208
|
|
|
199
209
|
@objc private func openChat() { onOpenChat?() }
|
|
200
210
|
|
|
211
|
+
@objc private func listenAgain() { onListenAgain?() }
|
|
212
|
+
|
|
213
|
+
/// The speaker while the answer is being said again: a stop button,
|
|
214
|
+
/// so a second click stops it.
|
|
215
|
+
func setReplaying(_ on: Bool) {
|
|
216
|
+
guard let b = listenButton else { return }
|
|
217
|
+
let look = ListenAgain.look(replaying: on)
|
|
218
|
+
b.image = NSImage(systemSymbolName: look.symbol, accessibilityDescription: look.label)
|
|
219
|
+
b.toolTip = look.label
|
|
220
|
+
b.setAccessibilityLabel(look.label)
|
|
221
|
+
}
|
|
222
|
+
|
|
201
223
|
/// Select-and-⌘C: the pill has no Edit menu to route the shortcut.
|
|
202
224
|
func copySelection() { NSApp.sendAction(#selector(NSText.copy(_:)), to: web, from: nil) }
|
|
203
225
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// The answer's Listen again button (#492): what it shows, and what a
|
|
4
|
+
/// click does. A click speaks the answer in the pill again, from its
|
|
5
|
+
/// start, in its agent's voice; a click while it plays stops it.
|
|
6
|
+
enum ListenAgain {
|
|
7
|
+
enum Click: Equatable {
|
|
8
|
+
/// Queue the answer again on the daemon's speaking queue.
|
|
9
|
+
case speak
|
|
10
|
+
/// Stop it, the same stop as the stop shortcut.
|
|
11
|
+
case stop
|
|
12
|
+
/// No answer to say: nothing happens.
|
|
13
|
+
case nothing
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static func click(replaying: Bool, text: String?) -> Click {
|
|
17
|
+
if replaying { return .stop }
|
|
18
|
+
guard let text, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return .nothing }
|
|
19
|
+
return .speak
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// The SF Symbol and the label (tooltip and screen reader) for a state.
|
|
23
|
+
static func look(replaying: Bool) -> (symbol: String, label: String) {
|
|
24
|
+
replaying ? ("stop.fill", "Stop listening") : ("speaker.wave.2", "Listen again")
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -62,6 +62,11 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
62
62
|
/// Waiting for our answer to be spoken by the daemon's queue. The door
|
|
63
63
|
/// lets go of it: the answer stays queued and plays after the turn.
|
|
64
64
|
private var speaking: Task<Void, Never>?
|
|
65
|
+
/// The answer in the pill, for Listen again (#492): what was said, by
|
|
66
|
+
/// which agent, in which voice.
|
|
67
|
+
private var shownAnswer: (text: String, agentID: String?, voice: VoiceChoice?)?
|
|
68
|
+
/// Listen again in progress; a second click stops it.
|
|
69
|
+
private var replaying: Task<Void, Never>?
|
|
65
70
|
/// Words said while our own turn was still running: they go next, and
|
|
66
71
|
/// the stale answer is not spoken.
|
|
67
72
|
private var followUp: String?
|
|
@@ -437,6 +442,7 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
437
442
|
return self.statusMenu.palette(of: self.shownAgent)
|
|
438
443
|
}
|
|
439
444
|
panel.answer.onOpenChat = { [weak self] in self?.openChat() }
|
|
445
|
+
panel.answer.onListenAgain = { [weak self] in self?.listenAgain() }
|
|
440
446
|
statusMenu.pillVisible = { [weak self] in self?.panel.isVisible ?? false }
|
|
441
447
|
statusMenu.onHidePill = { [weak self] in self?.dismissPill() }
|
|
442
448
|
statusMenu.pillReduced = { [weak self] in self?.panel.reduced ?? false }
|
|
@@ -590,6 +596,8 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
590
596
|
/// Open the microphone with no key held.
|
|
591
597
|
private func listenHandsFree(followUp: Bool) {
|
|
592
598
|
guard !busy, !recorder.isRecording else { return }
|
|
599
|
+
// A replay is playing (#492): the follow-up window would hear it.
|
|
600
|
+
if followUp && replaying != nil { return }
|
|
593
601
|
recorder.endOfTurn = settings?.general.endOfTurn ?? "vad"
|
|
594
602
|
do {
|
|
595
603
|
try recorder.start()
|
|
@@ -665,9 +673,50 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
665
673
|
asideSpeaker = nil
|
|
666
674
|
lastSpokeAt = Date()
|
|
667
675
|
Task { await Speech.stopAll() }
|
|
676
|
+
endReplay()
|
|
668
677
|
if !recorder.isRecording { panel.render(rest) }
|
|
669
678
|
}
|
|
670
679
|
|
|
680
|
+
/// Listen again (#492): the answer in the pill, said again from its
|
|
681
|
+
/// start in its agent's voice. It waits its turn on the daemon's
|
|
682
|
+
/// speaking queue like any line. A second click stops it, the same
|
|
683
|
+
/// stop as the stop shortcut.
|
|
684
|
+
private func listenAgain() {
|
|
685
|
+
switch ListenAgain.click(replaying: replaying != nil, text: shownAnswer?.text) {
|
|
686
|
+
case .nothing: return
|
|
687
|
+
case .stop: stopSpeaking(); return
|
|
688
|
+
case .speak: break
|
|
689
|
+
}
|
|
690
|
+
guard let shown = shownAnswer else { return }
|
|
691
|
+
// An open microphone would take the replay for the listener's
|
|
692
|
+
// words: it closes without sending.
|
|
693
|
+
if recorder.isRecording {
|
|
694
|
+
stopPolling()
|
|
695
|
+
_ = recorder.stop()
|
|
696
|
+
panel.render(rest)
|
|
697
|
+
}
|
|
698
|
+
Log.info("listen again (\(shown.agentID ?? "?"))")
|
|
699
|
+
// Nothing else on screen: the orb speaks while it is said.
|
|
700
|
+
let onScreen = !busy && asideSpeaker == nil
|
|
701
|
+
if onScreen { panel.render(.saying(shown.text)) }
|
|
702
|
+
panel.answer.setReplaying(true)
|
|
703
|
+
let line = Task { await Speech.say(shown.text, agentID: shown.agentID, kind: "answer", voice: shown.voice) }
|
|
704
|
+
replaying = line
|
|
705
|
+
Task { @MainActor [weak self] in
|
|
706
|
+
await line.value
|
|
707
|
+
guard let self, self.replaying == line else { return }
|
|
708
|
+
self.endReplay()
|
|
709
|
+
if onScreen && !self.busy && !self.recorder.isRecording && self.asideSpeaker == nil { self.panel.render(self.rest) }
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/// The speaker button back to Listen again.
|
|
714
|
+
private func endReplay() {
|
|
715
|
+
replaying?.cancel()
|
|
716
|
+
replaying = nil
|
|
717
|
+
panel.answer.setReplaying(false)
|
|
718
|
+
}
|
|
719
|
+
|
|
671
720
|
private func startListening() {
|
|
672
721
|
// A held key overrides any hands-free window that is open, so the
|
|
673
722
|
// two ways of talking never fight over the microphone.
|
|
@@ -684,6 +733,9 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
684
733
|
Speech.stop()
|
|
685
734
|
speaking?.cancel()
|
|
686
735
|
speaking = nil
|
|
736
|
+
// A replay waits, hushed, like any answer, and plays again on
|
|
737
|
+
// resume: the button keeps it, so a click stops it rather than
|
|
738
|
+
// queueing a second copy. It lets go when the daemon's wait ends.
|
|
687
739
|
lastSpokeAt = Date()
|
|
688
740
|
talkCheck = Task { await AgentClient.hush() }
|
|
689
741
|
Log.info("door: opened\(busy ? " (a turn is running)" : "")")
|
|
@@ -831,6 +883,7 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
831
883
|
buttons: answer.buttons, imageURL: answer.imageURL) {
|
|
832
884
|
panel.showAnswer(spoken: answer.text, written: answer.written,
|
|
833
885
|
buttons: answer.buttons, imageURL: answer.imageURL)
|
|
886
|
+
shownAnswer = (answer.text, answer.agentID ?? agent, answer.voice)
|
|
834
887
|
}
|
|
835
888
|
// Nothing else on screen: the pill shows this answer, its
|
|
836
889
|
// orb in this agent's colour, while it is spoken.
|
|
@@ -896,6 +949,7 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
896
949
|
buttons: answer.buttons, imageURL: answer.imageURL) {
|
|
897
950
|
panel.showAnswer(spoken: answer.text, written: answer.written,
|
|
898
951
|
buttons: answer.buttons, imageURL: answer.imageURL)
|
|
952
|
+
shownAnswer = (answer.text, answer.agentID, voice)
|
|
899
953
|
} else {
|
|
900
954
|
panel.collapse()
|
|
901
955
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as F,b as L,c as U,d as N,e as O,f as H,g as j}from"./chunk-U2CKL755.js";import{b as B,c as D,d as A,e as P,g as M}from"./chunk-
|
|
1
|
+
import{a as F,b as L,c as U,d as N,e as O,f as H,g as j}from"./chunk-U2CKL755.js";import{b as B,c as D,d as A,e as P,g as M}from"./chunk-HSYNOMM2.js";import"./chunk-FBEMUCBO.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useEffect as R,useReducer as V,useRef as G}from"react";import{Box as i,Text as o,useApp as W,useInput as J}from"ink";import{randomUUID as z}from"crypto";async function*q(e){let r=[];e.type&&r.push(`type=${encodeURIComponent(e.type)}`);let t=`${e.baseUrl.replace(/\/+$/,"")}/events${r.length?`?${r.join("&")}`:""}`,n={Accept:"text/event-stream"};e.token&&(n.Authorization=`Bearer ${e.token}`);let s=await fetch(t,{headers:n,signal:e.signal});if(!s.ok||!s.body)throw new Error(`SSE connect failed: HTTP ${s.status}`);let u=s.body.getReader(),p=new TextDecoder,y="";try{for(;;){let{done:f,value:l}=await u.read();if(f)return;y+=p.decode(l,{stream:!0});let d;for(;(d=y.indexOf(`
|
|
2
2
|
|
|
3
3
|
`))>=0;){let h=y.slice(0,d);y=y.slice(d+2);let m=X(h);m&&(yield m)}}}finally{try{u.releaseLock()}catch{}}}function X(e){let r="message",t="";for(let s of e.split(`
|
|
4
4
|
`))s.startsWith("event: ")?r=s.slice(7):s.startsWith("data: ")&&(t=s.slice(6));if(!t)return null;let n;try{n=JSON.parse(t)}catch{n=t}return{event:r,data:n}}import{jsx as a,jsxs as c}from"react/jsx-runtime";function $(e,r){return r<=0||e<0?0:e>=r?r-1:e}function E(){return`tui:${z().slice(0,12)}`}function k(e,r){let t=[...e,r];return t.length>50&&t.splice(0,t.length-50),t}function Y(e,r){switch(r.type){case"agents":return{...e,agents:r.data,cursor:{...e.cursor,agents:$(e.cursor.agents,r.data.length)}};case"processes":return{...e,processes:r.data,cursor:{...e.cursor,processes:$(e.cursor.processes,r.data.length)}};case"crons":return{...e,crons:r.data};case"event":{let t=[r.row,...e.events];t.length>200&&(t.length=200);let n=e.channels;return r.channelTally&&(n=new Map(e.channels),n.set(r.channelTally.channel,r.channelTally)),{...e,events:t,channels:n}}case"connError":return{...e,connError:r.error};case"tick":return{...e,lastTick:Date.now()};case"focus":return{...e,focus:r.pane};case"cursor":{let t=r.pane==="agents"?e.agents.length:r.pane==="processes"?e.processes.length:e.events.length;return{...e,cursor:{...e.cursor,[r.pane]:$(e.cursor[r.pane]+r.delta,t)}}}case"bottomRight":return{...e,bottomRight:r.pane};case"chatStart":return{...e,chat:{active:!0,agentId:r.agentId,chatId:E(),history:[],text:"",status:"idle",error:null}};case"chatExit":return{...e,chat:{...e.chat,active:!1}};case"chatClear":return{...e,chat:{...e.chat,chatId:E(),history:[],text:"",status:"idle",error:null}};case"chatText":return{...e,chat:{...e.chat,text:r.text}};case"chatSubmitStart":return{...e,chat:{...e.chat,history:k(e.chat.history,r.you),text:"",status:"sending",error:null}};case"chatSubmitDone":return{...e,chat:{...e.chat,history:k(e.chat.history,r.reply),status:"idle",error:null}};case"chatSubmitError":return{...e,chat:{...e.chat,history:k(e.chat.history,{role:"error",text:r.error,at:Date.now()}),status:"idle",error:r.error}};case"chatStreamStart":{let t=k(e.chat.history,r.you),n=k(t,{role:"agent",text:"",at:Date.now(),streaming:!0,tools:[]});return{...e,chat:{...e.chat,history:n,text:"",status:"sending",error:null}}}case"chatStreamDelta":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,text:n.text+r.text}),{...e,chat:{...e.chat,history:t}}}case"chatStreamThinking":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,thinking:(n.thinking??"")+r.text}),{...e,chat:{...e.chat,history:t}}}case"chatStreamTool":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,tools:[...n.tools??[],{name:r.name,arg:r.arg,error:r.error}]}),{...e,chat:{...e.chat,history:t}}}case"chatStreamEnd":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]=r.error?{...n,streaming:!1,role:"error",text:r.error}:{...n,streaming:!1,elapsedMs:r.elapsedMs,outTokens:r.outTokens}),{...e,chat:{...e.chat,history:t,status:"idle",error:r.error??null}}}case"toast":return{...e,toast:{text:r.text,color:r.color,at:Date.now()}};case"clearToast":return{...e,toast:null}}}var _={agents:[],processes:[],crons:[],events:[],channels:new Map,connError:null,lastTick:0,focus:"agents",cursor:{agents:0,processes:0,events:0},bottomRight:"crons",chat:{active:!1,agentId:null,chatId:E(),history:[],text:"",status:"idle",error:null},toast:null};function be({conn:e,pollMs:r=3e3}){let[t,n]=V(Y,_),{exit:s}=W(),u=G(null),p=G(null),y=t.agents.map(l=>l.id),f=t.chat.active?L(t.chat.text,y,process.cwd()):null;return R(()=>{if(!t.toast)return;let l=setTimeout(()=>n({type:"clearToast"}),3500);return()=>clearTimeout(l)},[t.toast]),J((l,d)=>{if(t.chat.active){if(d.escape){n({type:"chatExit"});return}if(d.ctrl&&l==="l"){n({type:"chatClear"});return}if(d.tab){let m=U(t.chat.text,p,y,process.cwd());m!==null&&n({type:"chatText",text:m});return}if(d.backspace||d.delete){p.current=null,n({type:"chatText",text:t.chat.text.slice(0,-1)});return}if(d.ctrl||d.meta)return;let h=N(l??"",d.return,t.chat.text);if(h.kind==="paste"||h.kind==="type"){p.current=null,n({type:"chatText",text:t.chat.text+h.text});return}if(h.kind==="continue"){n({type:"chatText",text:h.buffer});return}if(h.kind==="submit"){let m=h.text.trim(),g=t.chat.agentId;if(!m||!g||t.chat.status==="sending"){n({type:"chatText",text:""});return}p.current=null;let b=Date.now(),w=t.chat.chatId;n({type:"chatStreamStart",you:{role:"you",text:m,at:b}}),(async()=>{try{let C=await M(e,g,m,{channel:"tui",chatId:w,onText:x=>n({type:"chatStreamDelta",text:x}),onThinking:x=>n({type:"chatStreamThinking",text:x}),onTool:x=>{x.status==="start"&&x.name?n({type:"chatStreamTool",name:x.name,arg:x.arg}):x.status==="result"&&x.error&&n({type:"chatStreamTool",name:x.name??"tool",error:!0})}});n({type:"chatStreamEnd",elapsedMs:Date.now()-b,outTokens:C.usage?.outputTokens,error:C.error})}catch(C){n({type:"chatStreamEnd",elapsedMs:Date.now()-b,error:C?.message||String(C)})}})();return}return}if(l==="q"||d.ctrl&&l==="c"){u.current?.abort(),s();return}if(d.tab){let h=["agents","processes","events"],m=h.indexOf(t.focus);n({type:"focus",pane:h[(m+1)%h.length]});return}if(l==="a"){n({type:"focus",pane:"agents"});return}if(l==="p"){n({type:"focus",pane:"processes"});return}if(l==="e"){n({type:"focus",pane:"events"});return}if(l==="c"){n({type:"bottomRight",pane:t.bottomRight==="crons"?"channels":"crons"});return}if(d.upArrow){n({type:"cursor",pane:t.focus,delta:-1});return}if(d.downArrow){n({type:"cursor",pane:t.focus,delta:1});return}if(d.return&&t.focus==="agents"){let h=t.agents[t.cursor.agents];if(!h){n({type:"toast",text:"no agent selected",color:"yellow"});return}n({type:"chatStart",agentId:h.id});return}if(l==="k"&&t.focus==="processes"){let h=t.processes[t.cursor.processes];if(!h){n({type:"toast",text:"no process selected",color:"yellow"});return}(async()=>{try{await P(e,h.key,"tui"),n({type:"toast",text:`killed ${h.key.agentId}/${h.key.channel}/${h.key.chatId}`,color:"green"})}catch(m){n({type:"toast",text:`kill failed: ${m?.message||m}`,color:"red"})}})();return}}),R(()=>{let l=new AbortController;u.current=l;let d=!1,h=async()=>{try{let[g,b,w]=await Promise.all([B(e,l.signal).catch(()=>[]),D(e,l.signal).catch(()=>[]),A(e,l.signal).catch(()=>[])]);if(d)return;n({type:"agents",data:g}),n({type:"processes",data:b}),n({type:"crons",data:w}),n({type:"tick"}),n({type:"connError",error:null})}catch(g){d||n({type:"connError",error:g?.message||String(g)})}};h();let m=setInterval(h,r);return()=>{d=!0,clearInterval(m),l.abort()}},[e.baseUrl,e.token,r]),R(()=>{let l=!1,d=new AbortController,h=new Map;return(async()=>{let m=500;for(;!l;){try{for await(let g of q({baseUrl:e.baseUrl,token:e.token,signal:d.signal})){let b=ae(g),w;if(g.event==="channel"&&typeof g.data?.channel=="string"){let S=h.get(g.data.channel)??{channel:g.data.channel,inbound:0,outbound:0,lastAt:0,lastPreview:""},C=S.inbound+(g.data.direction==="in"?1:0),x=S.outbound+(g.data.direction==="out"?1:0);w={channel:g.data.channel,inbound:C,outbound:x,lastAt:b.at,lastPreview:(g.data.textPreview||"").slice(0,60)},h.set(g.data.channel,w)}n({type:"event",row:b,channelTally:w}),m=500}}catch(g){if(l)return;n({type:"connError",error:`events: ${g?.message||g}`})}await new Promise(g=>setTimeout(g,m)),m=Math.min(m*2,1e4)}})(),()=>{l=!0,d.abort()}},[e.baseUrl,e.token]),c(i,{flexDirection:"column",width:"100%",children:[a(K,{conn:e,lastTick:t.lastTick,connError:t.connError,chat:t.chat}),c(i,{flexDirection:"row",flexGrow:1,children:[c(i,{flexDirection:"column",width:"50%",children:[a(v,{title:"AGENTS",focused:!t.chat.active&&t.focus==="agents",children:a(Z,{rows:t.agents,cursor:t.cursor.agents,focused:!t.chat.active&&t.focus==="agents",talkingTo:t.chat.active?t.chat.agentId:null})}),a(v,{title:"PROCESSES",focused:!t.chat.active&&t.focus==="processes",children:a(ee,{rows:t.processes,cursor:t.cursor.processes,focused:!t.chat.active&&t.focus==="processes"})})]}),t.chat.active?a(oe,{chat:t.chat,suggest:f,agents:t.agents}):c(i,{flexDirection:"column",width:"50%",children:[a(v,{title:"LIVE EVENTS",focused:t.focus==="events",children:a(ne,{rows:t.events,cursor:t.cursor.events,focused:t.focus==="events"})}),a(v,{title:t.bottomRight==="crons"?"CRONS / SCHEDULES":"CHANNELS",focused:!1,children:t.bottomRight==="crons"?a(te,{rows:t.crons}):a(re,{rows:Array.from(t.channels.values())})})]})]}),a(Q,{focus:t.focus,bottomRight:t.bottomRight,chat:t.chat,toast:t.toast})]})}function K({conn:e,lastTick:r,connError:t,chat:n}){let s=t?c(o,{color:"red",children:["\u25CF ",t]}):r===0?a(o,{color:"yellow",children:"\u25CF connecting\u2026"}):a(o,{color:"green",children:"\u25CF live"}),u=n.active?c(o,{color:"green",bold:!0,children:["CHAT @",n.agentId]}):a(o,{bold:!0,children:"agentx tui"});return c(i,{paddingX:1,justifyContent:"space-between",children:[a(i,{children:u}),a(o,{dimColor:!0,children:e.baseUrl}),a(i,{children:s})]})}function Q({focus:e,bottomRight:r,chat:t,toast:n}){let s=t.active?["[Enter] send","[Esc] exit chat","[Ctrl-L] new session"]:[`[Tab/a/p/e] focus (now: ${e})`,e==="agents"?"[Enter] chat":null,e==="processes"?"[k] kill":null,`[c] ${r==="crons"?"\u2192channels":"\u2192crons"}`,"[\u2191/\u2193] move","[q] quit"].filter(Boolean);return c(i,{paddingX:1,borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,justifyContent:"space-between",children:[a(o,{dimColor:!0,children:s.join(" \xB7 ")}),n?a(o,{color:n.color,children:n.text}):a(o,{children:" "})]})}function v({title:e,focused:r,children:t}){return c(i,{flexDirection:"column",width:"100%",borderStyle:r?"double":"single",borderColor:r?"cyan":void 0,paddingX:1,children:[c(o,{bold:!0,color:r?"cyan":"white",children:[e,r?" \u25CF":""]}),a(i,{flexDirection:"column",marginTop:1,children:t})]})}function I(e,r){return e&&r?{inverse:!0}:{}}function Z({rows:e,cursor:r,focused:t,talkingTo:n}){return e.length===0?a(o,{dimColor:!0,children:"no agents"}):a(i,{flexDirection:"column",children:e.slice(0,12).map((s,u)=>{let p=I(t,u===r),y=s.errors>0?"red":s.active>0?"yellow":"green",f=s.id===n;return c(i,{children:[a(o,{...p,color:y,children:"\u25CF"}),c(o,{...p,children:[" ",T(s.name,14)]}),c(o,{...p,children:[T(s.tier,6)," "]}),c(o,{...p,children:[s.active,"/",s.total]}),s.errors>0?c(o,{...p,color:"red",children:[" err=",s.errors]}):null,f?a(o,{color:"green",children:" \u2194 chatting"}):null]},s.id)})})}function ee({rows:e,cursor:r,focused:t}){if(e.length===0)return a(o,{dimColor:!0,children:"no live processes"});let n=Date.now();return a(i,{flexDirection:"column",children:e.slice(0,12).map((s,u)=>{let p=I(t,u===r),y=Math.max(0,Math.round((n-(s.lastTurnAt||s.spawnedAt))/1e3)),f=s.state==="dead"?"red":s.state==="warm-hot"?"green":"yellow";return c(i,{children:[a(o,{...p,color:f,children:T(s.state,10)}),a(o,{...p,children:T(s.key.agentId,12)}),a(o,{...p,children:T(s.key.channel,10)}),c(o,{...p,children:[s.turnCount,"t ",y,"s"]})]},`${s.key.agentId}-${s.key.channel}-${s.key.chatId}-${u}`)})})}function te({rows:e}){return e.length===0?a(o,{dimColor:!0,children:"no crons"}):a(i,{flexDirection:"column",children:e.slice(0,12).map(r=>{let t=r.enabled?r.consecutiveErrors>0?a(o,{color:"red",children:"err"}):a(o,{color:"green",children:"ok"}):a(o,{dimColor:!0,children:"off"}),n=r.nextRun?new Date(r.nextRun).toLocaleTimeString():"\u2014";return c(i,{children:[a(o,{children:T(r.id,16)}),a(o,{dimColor:!0,children:T(r.schedule,12)}),a(o,{children:T(n,10)}),a(i,{children:t})]},r.id)})})}function re({rows:e}){if(e.length===0)return a(o,{dimColor:!0,children:"(waiting for channel events\u2026)"});let r=[...e].sort((t,n)=>n.lastAt-t.lastAt);return a(i,{flexDirection:"column",children:r.slice(0,12).map(t=>c(i,{children:[a(o,{children:T(t.channel,12)}),c(o,{color:"cyan",children:["\u2190",T(String(t.inbound),4)]}),c(o,{color:"magenta",children:["\u2192",T(String(t.outbound),4)]}),a(o,{dimColor:!0,children:t.lastPreview})]},t.channel))})}function ne({rows:e,cursor:r,focused:t}){return e.length===0?a(o,{dimColor:!0,children:"(waiting for events\u2026)"}):a(i,{flexDirection:"column",children:e.slice(0,18).map((n,s)=>{let u=I(t,s===r);return c(i,{children:[a(o,{...u,dimColor:!0,children:new Date(n.at).toLocaleTimeString().padEnd(10)}),a(o,{...u,color:ce(n.kind),children:T(n.kind,8)}),a(o,{...u,children:n.line})]},`${n.at}-${s}`)})})}function oe({chat:e,suggest:r,agents:t}){let n=e.history.slice(-14),s=t.find(f=>f.id===e.agentId),u=H(s?.tier??"",s?.model),p=e.status==="sending"?[...e.history].reverse().find(f=>f.role==="agent"&&f.streaming):void 0,y=e.status==="sending"?a(O,{startedAt:p?.at??Date.now(),phase:p?.text?"responding":"thinking",indent:""}):e.error?c(o,{color:"red",children:["\u25CF ",e.error]}):a(o,{dimColor:!0,children:"\u25CF ready"});return c(i,{flexDirection:"column",width:"50%",borderStyle:"double",borderColor:"green",paddingX:1,children:[c(i,{justifyContent:"space-between",children:[c(o,{bold:!0,color:"green",children:["CHAT \xB7 @",e.agentId]}),a(i,{children:y})]}),c(o,{children:[c(o,{color:u.color,bold:!0,children:[u.glyph," ",u.label]}),s?.model?c(o,{dimColor:!0,children:[" ",j(s.model)]}):null,c(o,{dimColor:!0,children:[" \xB7 ",e.chatId]})]}),a(i,{flexDirection:"column",flexGrow:1,marginTop:1,children:n.length===0?a(o,{dimColor:!0,children:"(type a message and press Enter \u2014 Esc exits, Ctrl-L starts fresh)"}):n.map((f,l)=>a(se,{turn:f,agentId:e.agentId},`${f.at}-${l}`))}),r?c(o,{dimColor:!0,children:[a(o,{color:"cyan",children:"\u21B9"})," ",r.items.slice(0,5).map((f,l)=>l===0?a(o,{color:"cyan",children:f},l):c(o,{children:[" ",f]},l))]}):null,c(i,{children:[a(o,{color:"cyan",children:"you \u203A "}),a(o,{children:e.text}),a(o,{inverse:!0,children:" "})]})]})}function se({turn:e,agentId:r}){if(e.role==="you")return c(i,{flexDirection:"column",marginBottom:1,children:[a(o,{color:"cyan",children:"you"}),e.text.split(`
|
|
5
5
|
`).map((s,u)=>c(o,{children:[" ",s]},u))]});if(e.role==="error")return c(i,{flexDirection:"column",marginBottom:1,children:[a(o,{color:"red",children:"error"}),c(o,{color:"red",children:[" ",e.text]})]});let t=e.elapsedMs!=null?` \xB7 ${(e.elapsedMs/1e3).toFixed(1)}s${e.outTokens!=null?`, ${e.outTokens} tok`:""}`:e.streaming?" \xB7 \u2026":"",n=F(e.text,58,{balance:e.streaming});return c(i,{flexDirection:"column",marginBottom:1,children:[c(o,{color:"green",children:["@",r??"agent",a(o,{dimColor:!0,children:t})]}),e.thinking?e.thinking.split(`
|
|
6
6
|
`).filter(s=>s.trim()).slice(-2).map((s,u)=>c(o,{dimColor:!0,italic:!0,children:[" ",s]},`th${u}`)):null,(e.tools??[]).map((s,u)=>c(o,{color:s.error?"red":"green",children:[" \u25CF ",c(o,{bold:!s.error,dimColor:s.error,children:[s.name,s.arg?c(o,{dimColor:!0,children:["(",s.arg,")"]}):null,s.error?" failed":""]})]},`tool${u}`)),n.split(`
|
|
7
7
|
`).slice(0,14).map((s,u)=>c(o,{children:[" ",s]},u))]})}function ae(e){let r=e.data??{},t=typeof r.at=="string"||typeof r.at=="number"?new Date(r.at).getTime():Date.now(),n="";switch(e.event){case"run":n=`${r.phase??""} ${r.workflowId??""} ${(r.runId??"").slice(0,8)} ${r.nodeId??""}`.trim();break;case"task":n=`${r.phase??""} ${r.workflowId??""} ${Array.isArray(r.assignedTo)?r.assignedTo.join(","):""} ${r.title?`"${r.title}"`:""}`.trim();break;case"signal":n=`${r.name??""} (${r.scope??""}) ${r.workflowId??""}`.trim();break;case"mesh":n=`${r.peer??""} ${r.healthy?"healthy":"lost"} ${r.delta??""}`.trim();break;case"channel":{n=`${r.direction==="in"?"\u2190":"\u2192"} ${r.channel??""}:${r.chatId??""} ${r.textPreview??""}`.trim();break}case"status":n=`node=${r.node??""} agents=${r.agents??0} active=${(r.active??[]).length}`;break;default:n=typeof r=="string"?r:JSON.stringify(r).slice(0,80)}return{at:Number.isFinite(t)?t:Date.now(),kind:e.event,line:n}}function ce(e){switch(e){case"run":return"cyan";case"task":return"magenta";case"signal":return"green";case"mesh":return"blue";case"channel":return"yellow";default:return"white"}}function T(e,r){let t=(e??"").toString();return t.length>=r?t.slice(0,r-1)+" ":t+" ".repeat(r-t.length)}export{be as App};
|
|
8
|
-
//# sourceMappingURL=App-
|
|
8
|
+
//# sourceMappingURL=App-7Z2PWARZ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{a as Y,b as Z,c as _,d as ee,e as te,f as ne,g as re}from"./chunk-U2CKL755.js";import{b as Q,g as X}from"./chunk-
|
|
1
|
+
import{a as Y,b as Z,c as _,d as ee,e as te,f as ne,g as re}from"./chunk-U2CKL755.js";import{b as Q,g as X}from"./chunk-HSYNOMM2.js";import"./chunk-FBEMUCBO.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useCallback as oe,useMemo as H,useRef as P,useState as k}from"react";import{Box as g,Text as t,useApp as he,useInput as xe,useStdout as Te}from"ink";import{randomUUID as se}from"crypto";var m={accent:"cyan",agent:"green",working:"magenta",error:"red",muted:"gray"},q="\u25C7 agentx",F="\u258C";import{jsx as c,jsxs as o}from"react/jsx-runtime";var ie="/help /agent <id> /agents /clear /who /exit",be=[{cmd:"/agent",desc:"switch the target agent (/agent <id>)"},{cmd:"/agents",desc:"list registered agents"},{cmd:"/clear",desc:"start a fresh session"},{cmd:"/who",desc:"show agent + chat id"},{cmd:"/help",desc:"list commands"},{cmd:"/exit",desc:"quit the chat"}];function Pe({conn:n,agentId:p,channel:f,chatId:a,agents:h}){let{exit:w}=he(),{stdout:O}=Te(),V=Math.max(40,Math.min((O?.columns||80)-4,100)),[z,U]=k([]),[$,S]=k(null),[T,le]=k(p),[A,ae]=k(h),[E,ue]=k(a),[y,x]=k(""),[J,de]=k(""),W=P([]),u=P(-1),M=P(null),R=P(null),v=$?.live??!1,j=H(()=>Z(y,A.map(s=>s.id),process.cwd()),[y,A]),N=H(()=>{let s=/^\/(\w*)$/.exec(y);if(!s)return null;let e=be.filter(r=>r.cmd.slice(1).startsWith(s[1].toLowerCase()));return e.length?e:null},[y]),b=s=>de(s),K=oe(s=>{let e=se().slice(0,8),r=Date.now(),i=new AbortController;R.current=i;let d={id:e,you:s,agentId:T,segs:[],live:!0,startedAt:r};S({...d});let L=()=>S({...d,segs:d.segs.map(C=>({...C}))});(async()=>{try{let C=await X(n,T,s,{channel:f,chatId:E,signal:i.signal,onText:l=>{let I=d.segs[d.segs.length-1];I&&I.type==="text"?I.content=(I.content??"")+l:d.segs.push({type:"text",content:l}),L()},onThinking:l=>{d.thinking=(d.thinking??"")+l,L()},onTool:l=>{l.status==="start"&&l.name?(d.segs.push({type:"tool",name:l.name,arg:l.arg}),L()):l.status==="result"&&l.error&&(d.segs.push({type:"tool",name:l.name??"tool",error:!0}),L())}});U(l=>[...l,{...d,live:!1,elapsedMs:Date.now()-r,outTokens:C.usage?.outputTokens,error:C.error}]),S(null)}catch(C){let l=i.signal.aborted||C?.name==="AbortError";U(I=>[...I,{...d,live:!1,elapsedMs:Date.now()-r,interrupted:l,error:l?void 0:C?.message||String(C)}]),S(null)}finally{R.current===i&&(R.current=null)}})()},[n,T,f,E]),me=oe(s=>{let e=s.trim();if(e){if(W.current.push(e),u.current=-1,e==="/exit"||e==="/quit"){w();return}if(e==="/help"){b(ie);return}if(e==="/who"){b(`@${T} \xB7 chatId=${E} \xB7 channel=${f}`);return}if(e==="/clear"){let r=`chat-cli:${se().slice(0,12)}`;ue(r),U([]),b(`fresh chatId=${r} (warm process dropped)`);return}if(e==="/agents"){Q(n).then(r=>{ae(r),b(r.map(i=>i.id===T?`[${i.id}]`:i.id).join(" "))}).catch(r=>b(`failed to list agents: ${r?.message||r}`));return}if(e.startsWith("/agent ")){let r=e.slice(7).replace(/^@/,"").trim();if(!r){b("usage: /agent <id>");return}if(!A.find(i=>i.id===r)){b(`unknown agent: @${r}`);return}le(r),b(`now talking to @${r}`);return}if(e.startsWith("/")){b(`unknown command \xB7 ${ie}`);return}K(e)}},[n,T,A,f,E,w,K]);xe((s,e)=>{if(e.ctrl&&s==="c"){w();return}if(e.escape){if(v&&R.current){R.current.abort();return}w();return}if(e.tab){if(N){x(N[0].cmd+" ");return}let i=_(y,M,A.map(d=>d.id),process.cwd());i!==null&&(x(i),u.current=-1);return}if(e.upArrow){let i=W.current;if(!i.length)return;u.current=u.current<0?i.length-1:Math.max(0,u.current-1),x(i[u.current]??"");return}if(e.downArrow){let i=W.current;if(u.current<0)return;if(u.current=u.current+1,u.current>=i.length){u.current=-1,x("");return}x(i[u.current]??"");return}if(e.backspace||e.delete){M.current=null,x(i=>i.slice(0,-1));return}if(e.ctrl||e.meta)return;let r=ee(s??"",e.return,y);switch(r.kind){case"paste":M.current=null,x(i=>i+r.text),u.current=-1;return;case"type":M.current=null,x(i=>i+r.text),u.current=-1;return;case"continue":x(r.buffer);return;case"submit":if(v)return;M.current=null,x(""),me(r.text);return;case"none":return}});let G=v?m.working:m.accent,ge=y.length?y.split(`
|
|
2
2
|
`):[""],B=A.find(s=>s.id===T),D=ne(B?.tier??"",B?.model),pe=O?.rows||24,fe=z.slice(-40);return o(g,{flexDirection:"column",height:pe,children:[o(g,{flexDirection:"column",flexGrow:1,justifyContent:"flex-end",overflow:"hidden",children:[z.length===0&&!$?o(g,{flexDirection:"column",children:[o(t,{children:[c(t,{color:m.accent,bold:!0,children:q}),c(t,{dimColor:!0,children:" \u2014 chat with "}),o(t,{color:m.accent,children:["@",T]}),c(t,{dimColor:!0,children:" via "}),o(t,{color:D.color,bold:!0,children:[D.glyph," ",D.label]}),B?.model?o(t,{dimColor:!0,children:[" (",B.model,")"]}):null]}),c(t,{dimColor:!0,children:"streaming \xB7 markdown \xB7 tools \xB7 type a message, or / for commands"})]}):null,fe.map(s=>c(ce,{turn:s,width:V},s.id)),$?c(ce,{turn:$,width:V}):null]}),N?c(g,{flexDirection:"column",marginTop:1,children:N.map((s,e)=>o(g,{children:[c(t,{color:e===0?m.accent:m.muted,bold:e===0,children:s.cmd.padEnd(10)}),c(t,{dimColor:!0,children:s.desc})]},s.cmd))}):j?o(g,{marginTop:1,children:[c(t,{color:m.accent,children:"\u21B9 "}),j.items.map((s,e)=>o(t,{color:e===0?m.accent:m.muted,children:[s,e<j.items.length-1?" ":""]},e))]}):J?c(g,{marginTop:1,children:c(t,{dimColor:!0,children:J})}):null,c(g,{borderStyle:"single",borderColor:G,borderLeft:!1,borderRight:!1,borderDimColor:!v,width:"100%",children:c(g,{flexDirection:"column",width:"100%",children:ge.map((s,e,r)=>o(g,{children:[c(t,{color:G,bold:!0,children:e===0?"\u203A ":" "}),c(t,{children:s}),e===r.length-1&&!v?c(t,{color:G,children:"\u258F"}):null]},e))})}),o(g,{justifyContent:"space-between",children:[o(t,{children:[c(t,{color:m.accent,bold:!0,children:q}),o(t,{dimColor:!0,children:[" \xB7 @",T," \xB7 "]}),o(t,{color:D.color,bold:!0,children:[D.glyph," ",D.label]}),B?.model?o(t,{dimColor:!0,children:[" ",re(B.model)]}):null]}),o(t,{dimColor:!0,children:["\u21B5 send / cmds @ mention esc ",v?"stop":"exit"]})]})]})}function ce({turn:n,width:p}){let f=H(()=>ye(n,p),[n,p]),a=n.segs.some(h=>h.type==="text"&&h.content);return o(g,{flexDirection:"column",marginBottom:1,children:[o(t,{color:m.accent,bold:!0,children:[F," you"]}),n.you.split(`
|
|
3
3
|
`).map((h,w)=>o(t,{color:"white",children:[" ",h]},`u${w}`)),o(t,{color:m.agent,bold:!0,children:[F," ",n.agentId??"agent"]}),n.thinking?c(g,{flexDirection:"column",children:we(n.thinking,n.live?3:2).map((h,w)=>o(t,{dimColor:!0,italic:!0,children:[" ",h]},`th${w}`))}):null,f,n.live?c(te,{startedAt:n.startedAt,phase:a?"responding":"thinking",hint:"esc to interrupt"}):n.interrupted?o(t,{dimColor:!0,children:[" \u2298 interrupted \xB7 ",(n.elapsedMs/1e3).toFixed(1),"s"]}):n.error?o(t,{color:"red",children:[" \u2717 ",n.error]}):n.elapsedMs!=null?o(t,{dimColor:!0,children:[" \xB7 ",(n.elapsedMs/1e3).toFixed(1),"s",n.outTokens!=null?`, ${n.outTokens} tok`:""]}):null]})}function we(n,p){return n.split(`
|
|
4
4
|
`).filter(a=>a.trim()).slice(-p)}function ye(n,p){let f=[];return n.segs.forEach((a,h)=>{a.type==="tool"?f.push(o(t,{color:a.error?"red":"green",children:[" ","\u25CF ",o(t,{bold:!a.error,dimColor:a.error,children:[a.name,a.arg?o(t,{dimColor:!0,children:["(",a.arg,")"]}):null,a.error?" failed":""]})]},h)):a.content&&f.push(c(t,{children:Ce(Y(a.content,p,{balance:n.live}))},h))}),f}function Ce(n){return n.split(`
|
|
5
5
|
`).map(p=>p.length?" "+p:p).join(`
|
|
6
6
|
`)}export{Pe as ChatApp};
|
|
7
|
-
//# sourceMappingURL=ChatApp-
|
|
7
|
+
//# sourceMappingURL=ChatApp-GFAIRLGZ.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{A as a,B as b,C as c}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=agent-
|
|
1
|
+
import{A as a,B as b,C as c}from"./chunk-S56ZGAFM.js";import"./chunk-SFQUP3BP.js";import"./chunk-QOYAX2FT.js";import"./chunk-2PJKGZWP.js";import"./chunk-7I7IEX4S.js";import"./chunk-JHCI6XCJ.js";import"./chunk-DSYKYZMT.js";import"./chunk-QIJLFPWE.js";export{a as createAgentContext,b as generate,c as generateStream};
|
|
2
|
+
//# sourceMappingURL=agent-LXLZGVW3.js.map
|