@artil-ai/pi 0.2.0 → 0.3.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/README.md +3 -2
- package/dist/index.js +67 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Artil for Pi
|
|
2
2
|
|
|
3
|
-
Install the package, which brings the Artil CLI, then sign in as
|
|
4
|
-
|
|
3
|
+
Install the package, which brings the Artil CLI, then start Pi and sign in as
|
|
4
|
+
your agent when it asks:
|
|
5
5
|
|
|
6
6
|
```sh
|
|
7
7
|
pi install npm:@artil-ai/pi
|
|
8
|
+
pi
|
|
8
9
|
```
|
|
9
10
|
|
|
10
11
|
Read more in the [Artil docs](https://docs.artil.ai/pi).
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,56 @@ function listen({ channel, restart, deliver, stopped }) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// sign-in.ts
|
|
33
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
34
|
+
import { createInterface as createInterface2 } from "node:readline";
|
|
35
|
+
function runArtil(args, { show = () => {}, env = {} } = {}) {
|
|
36
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
37
|
+
const artil = spawn2("artil", args, {
|
|
38
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
39
|
+
env: { ...process.env, ...env }
|
|
40
|
+
});
|
|
41
|
+
let problem = "";
|
|
42
|
+
createInterface2({ input: artil.stdout }).on("line", (line) => {
|
|
43
|
+
if (line.trim())
|
|
44
|
+
show(line.trim());
|
|
45
|
+
});
|
|
46
|
+
artil.stderr.on("data", (chunk) => {
|
|
47
|
+
problem += chunk.toString();
|
|
48
|
+
});
|
|
49
|
+
artil.on("error", (error) => resolve({ ok: false, problem: error.message }));
|
|
50
|
+
artil.on("close", (code) => resolve({ ok: code === 0, problem: problem.trim() }));
|
|
51
|
+
return promise;
|
|
52
|
+
}
|
|
53
|
+
var signInChoices = {
|
|
54
|
+
browser: "Sign in in the browser",
|
|
55
|
+
token: "Paste a token",
|
|
56
|
+
later: "Not now"
|
|
57
|
+
};
|
|
58
|
+
async function loginEnv(ui, choice) {
|
|
59
|
+
if (choice === signInChoices.browser)
|
|
60
|
+
return {};
|
|
61
|
+
if (choice !== signInChoices.token)
|
|
62
|
+
return;
|
|
63
|
+
const token = (await ui.input("Artil token", "artil_…"))?.trim();
|
|
64
|
+
return token ? { ARTIL_TOKEN: token } : undefined;
|
|
65
|
+
}
|
|
66
|
+
async function signedIn(ui) {
|
|
67
|
+
if ((await runArtil(["auth", "status"])).ok)
|
|
68
|
+
return true;
|
|
69
|
+
const choice = await ui.select("Sign in to Artil, so Pi hears about your agent's new messages", Object.values(signInChoices));
|
|
70
|
+
const env = await loginEnv(ui, choice);
|
|
71
|
+
if (!env)
|
|
72
|
+
return false;
|
|
73
|
+
const { ok, problem } = await runArtil(["auth", "login"], {
|
|
74
|
+
show: (line) => ui.notify(line, "info"),
|
|
75
|
+
env
|
|
76
|
+
});
|
|
77
|
+
if (!ok)
|
|
78
|
+
ui.notify(`Could not sign in to Artil. ${problem}`, "error");
|
|
79
|
+
return ok;
|
|
80
|
+
}
|
|
81
|
+
|
|
32
82
|
// index.ts
|
|
33
83
|
function addBundledArtil() {
|
|
34
84
|
const artil = dirname(createRequire(import.meta.url).resolve("artil-ai/package.json"));
|
|
@@ -38,23 +88,30 @@ function addBundledArtil() {
|
|
|
38
88
|
}
|
|
39
89
|
function hearNewMessages(pi) {
|
|
40
90
|
let listening;
|
|
91
|
+
let sessions = 0;
|
|
41
92
|
addBundledArtil();
|
|
42
93
|
pi.on("session_start", (_event, ctx) => {
|
|
43
94
|
if (!ctx.hasUI)
|
|
44
95
|
return;
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
96
|
+
const session = ++sessions;
|
|
97
|
+
signedIn(ctx.ui).then((ready) => {
|
|
98
|
+
if (!ready || session !== sessions)
|
|
99
|
+
return;
|
|
100
|
+
const stop = listen({
|
|
101
|
+
channel: "pi-channel",
|
|
102
|
+
restart: "run /reload",
|
|
103
|
+
deliver: ({ content, meta = {} }) => {
|
|
104
|
+
if (listening !== stop)
|
|
105
|
+
return;
|
|
106
|
+
pi.sendMessage({ customType: "artil-messages", content, display: true, details: meta }, { deliverAs: "followUp", triggerTurn: true });
|
|
107
|
+
},
|
|
108
|
+
stopped: (problem) => ctx.ui.notify(`Pi no longer hears about new messages. ${problem}`, "error")
|
|
109
|
+
});
|
|
110
|
+
listening = stop;
|
|
54
111
|
});
|
|
55
|
-
listening = stop;
|
|
56
112
|
});
|
|
57
113
|
pi.on("session_shutdown", () => {
|
|
114
|
+
sessions++;
|
|
58
115
|
listening?.();
|
|
59
116
|
listening = undefined;
|
|
60
117
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artil-ai/pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Email, SMS and Telegram for Pi. Your agent gets its own Artil inbox and phone number to read and answer messages.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prepack": "bun run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"artil-ai": "0.23.
|
|
37
|
+
"artil-ai": "0.23.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@artil-ai/channel": "workspace:*",
|