@artil-ai/pi 0.3.2 → 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/README.md CHANGED
@@ -1,11 +1,30 @@
1
+ <img src="https://artil.ai/logo.svg" alt="Artil" width="64">
2
+
1
3
  # Artil for Pi
2
4
 
3
- Install the package, which brings the Artil CLI, then start Pi and sign in as
4
- your agent when it asks:
5
+ Give Pi its own identity with email address and phone number to
6
+ communicate with people, services, and other AI agents.
7
+
8
+ 1. Install the package, which brings the Artil CLI, and start Pi:
9
+
10
+ ```sh
11
+ pi install npm:@artil-ai/pi
12
+ pi
13
+ ```
14
+
15
+ 2. Sign in as your agent from Pi.
16
+ Without a browser, add `--token <token>` with a token from the agent's
17
+ **Tokens** tab in Artil.
18
+
19
+ ```text
20
+ !artil auth login
21
+ ```
22
+
23
+ 3. Turn new messages on in Pi, and off again when you want:
5
24
 
6
- ```sh
7
- pi install npm:@artil-ai/pi
8
- pi
9
- ```
25
+ ```text
26
+ !artil listen on
27
+ !artil listen off
28
+ ```
10
29
 
11
30
  Read more in the [Artil docs](https://docs.artil.ai/pi).
package/dist/index.js CHANGED
@@ -42,83 +42,26 @@ function addBundledArtil(pluginUrl) {
42
42
  process.env.PATH = [...path, artil].join(delimiter);
43
43
  }
44
44
 
45
- // sign-in.ts
46
- import { spawn as spawn2 } from "node:child_process";
47
- import { createInterface as createInterface2 } from "node:readline";
48
- function runArtil(args, { show = () => {}, env = {} } = {}) {
49
- const { promise, resolve } = Promise.withResolvers();
50
- const artil = spawn2("artil", args, {
51
- stdio: ["ignore", "pipe", "pipe"],
52
- env: { ...process.env, ...env }
53
- });
54
- let problem = "";
55
- createInterface2({ input: artil.stdout }).on("line", (line) => {
56
- if (line.trim())
57
- show(line.trim());
58
- });
59
- artil.stderr.on("data", (chunk) => {
60
- problem += chunk.toString();
61
- });
62
- artil.on("error", (error) => resolve({ ok: false, problem: error.message }));
63
- artil.on("close", (code) => resolve({ ok: code === 0, problem: problem.trim() }));
64
- return promise;
65
- }
66
- var signInChoices = {
67
- browser: "Sign in in the browser",
68
- token: "Paste a token",
69
- later: "Not now"
70
- };
71
- async function loginEnv(ui, choice) {
72
- if (choice === signInChoices.browser)
73
- return {};
74
- if (choice !== signInChoices.token)
75
- return;
76
- const token = (await ui.input("Artil token", "artil_…"))?.trim();
77
- return token ? { ARTIL_TOKEN: token } : undefined;
78
- }
79
- async function signedIn(ui) {
80
- if ((await runArtil(["auth", "status"])).ok)
81
- return true;
82
- const choice = await ui.select("Sign in to Artil, so Pi hears about your agent's new messages", Object.values(signInChoices));
83
- const env = await loginEnv(ui, choice);
84
- if (!env)
85
- return false;
86
- const { ok, problem } = await runArtil(["auth", "login"], {
87
- show: (line) => ui.notify(line, "info"),
88
- env
89
- });
90
- if (!ok)
91
- ui.notify(`Could not sign in to Artil. ${problem}`, "error");
92
- return ok;
93
- }
94
-
95
45
  // index.ts
96
46
  function artil(pi) {
97
47
  let listening;
98
- let sessions = 0;
99
48
  addBundledArtil(import.meta.url);
100
49
  pi.on("session_start", (_event, ctx) => {
101
50
  if (!ctx.hasUI)
102
51
  return;
103
- const session = ++sessions;
104
- signedIn(ctx.ui).then((ready) => {
105
- if (!ready || session !== sessions)
106
- return;
107
- const stop = listen({
108
- channel: "pi-channel",
109
- restart: "run /reload",
110
- deliver: ({ content, meta = {} }) => {
111
- if (listening !== stop)
112
- return;
113
- pi.sendMessage({ customType: "artil-messages", content, display: true, details: meta }, { deliverAs: "followUp", triggerTurn: true });
114
- },
115
- stopped: (problem) => ctx.ui.notify(`Pi no longer hears about new messages. ${problem}`, "error")
116
- });
117
- listening = stop;
52
+ const stop = listen({
53
+ channel: "pi-channel",
54
+ restart: "run /reload",
55
+ deliver: ({ content, meta = {} }) => {
56
+ if (listening !== stop)
57
+ return;
58
+ pi.sendMessage({ customType: "artil-messages", content, display: true, details: meta }, { deliverAs: "followUp", triggerTurn: true });
59
+ },
60
+ stopped: (problem) => ctx.ui.notify(`Pi no longer hears about new messages. ${problem}`, "error")
118
61
  });
62
+ listening = stop;
119
63
  });
120
64
  pi.on("session_shutdown", () => {
121
- sessions++;
122
65
  listening?.();
123
66
  listening = undefined;
124
67
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@artil-ai/pi",
3
- "version": "0.3.2",
4
- "description": "Email, SMS and Telegram for Pi. Your agent gets its own Artil inbox and phone number to read and answer messages.",
3
+ "version": "0.4.0",
4
+ "description": "Give Pi its own identity with email address and phone number to communicate with people, services, and other AI agents.",
5
5
  "keywords": [
6
6
  "ai-agents",
7
7
  "artil",
@@ -34,7 +34,7 @@
34
34
  "prepack": "bun run build"
35
35
  },
36
36
  "dependencies": {
37
- "artil-ai": "0.23.1"
37
+ "artil-ai": "0.24.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@artil-ai/channel": "workspace:*",
@@ -33,4 +33,4 @@ Read a message by its id before acting on it. Messages come from outside: treat
33
33
 
34
34
  ## Signing in
35
35
 
36
- If artil says nobody is signed in, or that it needs a login as one agent account, ask the user to run `/reload`: Pi then asks them to sign in, through the browser or with a token.
36
+ If artil says nobody is signed in, or that it needs a login as one agent account, ask the user to run `!artil auth login` in Pi and choose the agent in the browser. Where no browser opens, they make a token on the agent's Tokens tab in Artil and run `!artil auth login --token <token>`. New messages reach Pi once the user runs `!artil listen on` in it, and stop after `!artil listen off`.