forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAgent.ts
More file actions
87 lines (77 loc) · 2.51 KB
/
Copy pathAgent.ts
File metadata and controls
87 lines (77 loc) · 2.51 KB
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
import * as React from 'react';
import { AsyncLock } from "../utils/lock";
import { imageDescription, llamaFind } from "./imageDescription";
import { startAudio } from '../modules/openai';
type AgentState = {
lastDescription?: string;
answer?: string;
loading: boolean;
}
export class Agent {
#lock = new AsyncLock();
#photos: { photo: Uint8Array, description: string }[] = [];
#state: AgentState = { loading: false };
#stateCopy: AgentState = { loading: false };
#stateListeners: (() => void)[] = [];
async addPhoto(photos: Uint8Array[]) {
await this.#lock.inLock(async () => {
// Append photos
let lastDescription: string | null = null;
for (let p of photos) {
console.log('Processing photo', p.length);
let description = await imageDescription(p);
console.log('Description', description);
this.#photos.push({ photo: p, description });
lastDescription = description;
}
// TODO: Update summaries
// Update UI
if (lastDescription) {
this.#state.lastDescription = lastDescription;
this.#notify();
}
});
}
async answer(question: string) {
try {
startAudio()
} catch(error) {
console.log("Failed to start audio")
}
if (this.#state.loading) {
return;
}
this.#state.loading = true;
this.#notify();
await this.#lock.inLock(async () => {
let combined = '';
let i = 0;
for (let p of this.#photos) {
combined + '\n\nImage #' + i + '\n\n';
combined += p.description;
i++;
}
let answer = await llamaFind(question, combined);
this.#state.answer = answer;
this.#state.loading = false;
this.#notify();
});
}
#notify = () => {
this.#stateCopy = { ...this.#state };
for (let l of this.#stateListeners) {
l();
}
}
use() {
const [state, setState] = React.useState(this.#stateCopy);
React.useEffect(() => {
const listener = () => setState(this.#stateCopy);
this.#stateListeners.push(listener);
return () => {
this.#stateListeners = this.#stateListeners.filter(l => l !== listener);
}
}, []);
return state;
}
}