|
17 | 17 | [:or |
18 | 18 | [:map |
19 | 19 | [:type (schema/flex-enum ["tts-say"])] |
20 | | - [:text :string]] |
| 20 | + [:text [:or :string [:vector :string]]]] |
21 | 21 | [:map |
22 | 22 | [:type (schema/flex-enum ["end-conversation"])]] |
23 | 23 | [:map |
|
50 | 50 | vals |
51 | 51 | (mapcat :functions) |
52 | 52 | (keep (fn [f] (get-in f [:function :transition-to]))) |
53 | | - (remove nil?)) |
| 53 | + (remove #(or (nil? %) |
| 54 | + (fn? %)))) |
54 | 55 | invalid-transition (first (remove nodes transitions))] |
55 | 56 | (when invalid-transition |
56 | 57 | (format "Unreachable node: %s" invalid-transition))))} |
|
60 | 61 | vals |
61 | 62 | (mapcat :functions) |
62 | 63 | (keep (fn [f] (get-in f [:function :transition-to]))) |
63 | | - (remove nil?))] |
| 64 | + (remove #(or (nil? %) |
| 65 | + (fn? %))))] |
64 | 66 | (every? defined-nodes transitions)))]]) |
65 | 67 |
|
66 | 68 | (defprotocol Scenario |
|
79 | 81 | [scenario tool] |
80 | 82 | (let [fndef (:function tool) |
81 | 83 | handler (:handler fndef) |
82 | | - next-node (:transition-to fndef) |
83 | | - cb #(set-node scenario next-node)] |
| 84 | + |
| 85 | + next-node-or-fn (:transition-to fndef) |
| 86 | + cb (if (fn? next-node-or-fn) |
| 87 | + (fn [args] |
| 88 | + (let [next-node (next-node-or-fn args)] |
| 89 | + (set-node scenario next-node))) |
| 90 | + (fn [_] (set-node scenario next-node-or-fn)))] |
84 | 91 | (cond-> tool |
85 | 92 | true (update-in [:function] dissoc :transition-to) |
86 | 93 | true (assoc-in [:function :transition-cb] cb) |
|
96 | 103 | initialized? (atom false) |
97 | 104 | tts-action? #(contains? #{:tts-say "tts-say"} (:type %)) |
98 | 105 | end-action? #(contains? #{:end-conversation "end-conversation"} (:type %)) |
99 | | - handle-action #(cond |
100 | | - (tts-action? %) (flow/inject flow flow-in-coord [(frame/speak-frame (:text %))]) |
101 | | - (end-action? %) (flow/stop flow) |
102 | | - :else ((:handler %)))] |
| 106 | + handle-action (fn [a] |
| 107 | + (cond |
| 108 | + (tts-action? a) |
| 109 | + (flow/inject flow flow-in-coord (if (coll? (:text a)) |
| 110 | + (mapv #(frame/speak-frame %) (:text a)) |
| 111 | + [(frame/speak-frame (:text a))])) |
| 112 | + (end-action? a) (flow/stop flow) |
| 113 | + :else ((:handler a))))] |
103 | 114 | (reify Scenario |
104 | 115 | (current-node [_] @current-node) |
105 | 116 | (set-node [this node-id] |
|
113 | 124 | (doseq [a (:post-actions node)] (handle-action a))) |
114 | 125 | (reset! current-node node-id) |
115 | 126 | (try |
116 | | - (t/log! "Sending new scenario") |
117 | | - (doseq [a (:pre-actions node)] (handle-action a)) |
118 | 127 | (flow/inject flow flow-in-coord [(frame/scenario-context-update {:messages append-context |
119 | 128 | :tools tools |
120 | 129 | :properties {:run-llm? (if (boolean? (:run-llm? node)) (:run-llm? node) true)}})]) |
| 130 | + (doseq [a (:pre-actions node)] (handle-action a)) |
121 | 131 |
|
122 | 132 | (catch Exception e |
123 | 133 | (t/log! :error e))))) |
|
0 commit comments