samoagent 0.3.0 → 0.4.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/dist/cli.js +103 -5
- package/package.json +1 -2
- package/CLAUDE.md +0 -67
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,92 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
13
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
|
|
35
|
+
// package.json
|
|
36
|
+
var require_package = __commonJS((exports, module) => {
|
|
37
|
+
module.exports = {
|
|
38
|
+
name: "samoagent",
|
|
39
|
+
version: "0.4.0",
|
|
40
|
+
description: "Let AI agents join Zoom and Google Meet calls as active participants.",
|
|
41
|
+
type: "module",
|
|
42
|
+
license: "Apache-2.0",
|
|
43
|
+
bin: {
|
|
44
|
+
samoagent: "dist/cli.js"
|
|
45
|
+
},
|
|
46
|
+
files: [
|
|
47
|
+
"dist/cli.js",
|
|
48
|
+
"dictionaries/",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"README.md",
|
|
51
|
+
"avatar.html",
|
|
52
|
+
"avatar.png",
|
|
53
|
+
"logo.svg"
|
|
54
|
+
],
|
|
55
|
+
repository: {
|
|
56
|
+
type: "git",
|
|
57
|
+
url: "git+https://github.com/NikolayS/samoagent.git"
|
|
58
|
+
},
|
|
59
|
+
homepage: "https://samoagent.dev/",
|
|
60
|
+
bugs: {
|
|
61
|
+
url: "https://github.com/NikolayS/samoagent/issues"
|
|
62
|
+
},
|
|
63
|
+
keywords: [
|
|
64
|
+
"ai-agent",
|
|
65
|
+
"meetings",
|
|
66
|
+
"recall-ai",
|
|
67
|
+
"zoom",
|
|
68
|
+
"google-meet",
|
|
69
|
+
"transcript",
|
|
70
|
+
"websocket"
|
|
71
|
+
],
|
|
72
|
+
engines: {
|
|
73
|
+
bun: ">=1.2.0"
|
|
74
|
+
},
|
|
75
|
+
publishConfig: {
|
|
76
|
+
access: "public"
|
|
77
|
+
},
|
|
78
|
+
scripts: {
|
|
79
|
+
samoagent: "bun src/cli.ts",
|
|
80
|
+
test: "bun test",
|
|
81
|
+
build: "tsc --noEmit && bun build src/cli.ts --target bun --outfile dist/cli.js && chmod +x dist/cli.js",
|
|
82
|
+
prepack: "bun run build"
|
|
83
|
+
},
|
|
84
|
+
devDependencies: {
|
|
85
|
+
"@types/bun": "latest",
|
|
86
|
+
typescript: "^5.9.3"
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
});
|
|
3
90
|
|
|
4
91
|
// src/config.ts
|
|
5
92
|
import { homedir } from "os";
|
|
@@ -1153,10 +1240,8 @@ async function cmdFrame(args, deps = {}) {
|
|
|
1153
1240
|
}
|
|
1154
1241
|
}
|
|
1155
1242
|
const raw = new Uint8Array(await resp2.arrayBuffer());
|
|
1243
|
+
writeFrameFiles(out, raw, metadata);
|
|
1156
1244
|
const output = archive && !args.out ? archiveFrameBytes(String(state.video_frame_dir ?? dirname4(out)), raw, metadata) : out;
|
|
1157
|
-
if (!(archive && !args.out)) {
|
|
1158
|
-
writeFrameFiles(output, raw, metadata);
|
|
1159
|
-
}
|
|
1160
1245
|
process.stdout.write(resolve3(output) + `
|
|
1161
1246
|
`);
|
|
1162
1247
|
return;
|
|
@@ -1280,7 +1365,7 @@ function serve(port, transcriptPath, options = {}) {
|
|
|
1280
1365
|
let payload = {};
|
|
1281
1366
|
try {
|
|
1282
1367
|
const body = await req.text();
|
|
1283
|
-
if (body.
|
|
1368
|
+
if (new TextEncoder().encode(body).byteLength > WEBHOOK_MAX_BYTES) {
|
|
1284
1369
|
return Response.json({ error: "payload too large" }, { status: 413 });
|
|
1285
1370
|
}
|
|
1286
1371
|
payload = body ? JSON.parse(body) : {};
|
|
@@ -1355,7 +1440,10 @@ async function cmdServe(args) {
|
|
|
1355
1440
|
// src/cli.ts
|
|
1356
1441
|
var USAGE = `usage: samoagent <command> [options]
|
|
1357
1442
|
|
|
1358
|
-
|
|
1443
|
+
Meeting I/O helper for AI agents \u2014 join Zoom & Google Meet calls,
|
|
1444
|
+
stream live transcripts, capture frames, and send chat messages.
|
|
1445
|
+
|
|
1446
|
+
Requires: RECALL_API_KEY env var (get one at recall.ai) and ngrok.
|
|
1359
1447
|
|
|
1360
1448
|
commands:
|
|
1361
1449
|
join <url> [--name N] [--dict D] [--port P] [--transcript-dir DIR] [--rtmp-url URL] [--rtmp] [--no-ws-video] [--frame-dir DIR]
|
|
@@ -1367,6 +1455,10 @@ commands:
|
|
|
1367
1455
|
dicts
|
|
1368
1456
|
watch
|
|
1369
1457
|
frame [--out FILE] [--archive] [bot_id]
|
|
1458
|
+
|
|
1459
|
+
flags:
|
|
1460
|
+
-h, --help Show this help message
|
|
1461
|
+
-v, --version Show version number
|
|
1370
1462
|
`;
|
|
1371
1463
|
|
|
1372
1464
|
class ArgError extends Error {
|
|
@@ -1550,6 +1642,12 @@ async function main() {
|
|
|
1550
1642
|
process.stdout.write(USAGE);
|
|
1551
1643
|
process.exit(argv.length === 0 ? 2 : 0);
|
|
1552
1644
|
}
|
|
1645
|
+
if (argv[0] === "--version" || argv[0] === "-v" || argv[0] === "-V") {
|
|
1646
|
+
const pkg = await Promise.resolve().then(() => __toESM(require_package(), 1));
|
|
1647
|
+
process.stdout.write(`samoagent ${pkg.version}
|
|
1648
|
+
`);
|
|
1649
|
+
process.exit(0);
|
|
1650
|
+
}
|
|
1553
1651
|
let args;
|
|
1554
1652
|
try {
|
|
1555
1653
|
args = parseArgs(argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samoagent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Let AI agents join Zoom and Google Meet calls as active participants.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"dictionaries/",
|
|
13
13
|
"LICENSE",
|
|
14
14
|
"README.md",
|
|
15
|
-
"CLAUDE.md",
|
|
16
15
|
"avatar.html",
|
|
17
16
|
"avatar.png",
|
|
18
17
|
"logo.svg"
|
package/CLAUDE.md
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# samoagent Agent Notes
|
|
2
|
-
|
|
3
|
-
Use samoagent to join a meeting, watch the live transcript, speak in meeting chat when asked, and capture the call view on demand.
|
|
4
|
-
|
|
5
|
-
## Preferred Flow
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
samoagent join "https://meet.google.com/..." --name Leo --dict postgresfm
|
|
9
|
-
samoagent watch
|
|
10
|
-
samoagent frame
|
|
11
|
-
samoagent leave
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Start `watch` immediately after `join` with your persistent monitor. Keep it running until the call ends. Each line is:
|
|
15
|
-
|
|
16
|
-
```text
|
|
17
|
-
[timestamp] Speaker: utterance
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
React in your agent session. Use meeting chat only for deliberate call-visible messages:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
samoagent chat "Short message to the meeting"
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Looking At The Call
|
|
27
|
-
|
|
28
|
-
Frame capture is on by default. Recall sends `video_separate_png.data` frames over the ngrok HTTPS/WSS tunnel. Frames stay in server memory; disk writes happen only when the agent calls:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
samoagent frame
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Default output is outside the repo:
|
|
35
|
-
|
|
36
|
-
```text
|
|
37
|
-
~/.samoagent/frames/latest.png
|
|
38
|
-
~/.samoagent/frames/latest.json
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Use explicit outputs only when needed:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
samoagent frame --out /tmp/call.png
|
|
45
|
-
samoagent frame --archive
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
`--archive` creates a timestamped filename with bot id, source type, and participant id.
|
|
49
|
-
|
|
50
|
-
## Mixed Video
|
|
51
|
-
|
|
52
|
-
Use RTMP only when separate PNG frames are not enough:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
samoagent join "https://zoom.us/j/..." --rtmp
|
|
56
|
-
samoagent join "https://zoom.us/j/..." --rtmp-url rtmp://HOST:1935/live/call
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
`--rtmp` needs ngrok TCP, which requires ngrok card verification. `--rtmp-url` needs a public RTMP receiver.
|
|
60
|
-
|
|
61
|
-
## End The Call
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
samoagent leave
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`leave` removes the bot, stops local helper processes, writes the `SAMOAGENT_CALL_ENDED` sentinel, and lets `watch` exit cleanly.
|