pinecall 0.4.0 → 0.5.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.
Files changed (203) hide show
  1. package/README.md +14 -6
  2. package/dist/cli/agent-files.d.ts +6 -0
  3. package/dist/cli/agent-files.d.ts.map +1 -0
  4. package/dist/cli/agent-files.js +40 -0
  5. package/dist/cli/agent-files.js.map +1 -0
  6. package/dist/cli/agent-lines.d.ts +23 -0
  7. package/dist/cli/agent-lines.d.ts.map +1 -0
  8. package/dist/cli/agent-lines.js +109 -0
  9. package/dist/cli/agent-lines.js.map +1 -0
  10. package/dist/cli/agent-versions.d.ts +12 -0
  11. package/dist/cli/agent-versions.d.ts.map +1 -0
  12. package/dist/cli/agent-versions.js +70 -0
  13. package/dist/cli/agent-versions.js.map +1 -0
  14. package/dist/cli/agent.d.ts +77 -0
  15. package/dist/cli/agent.d.ts.map +1 -0
  16. package/dist/cli/agent.js +192 -0
  17. package/dist/cli/agent.js.map +1 -0
  18. package/dist/cli/chat.d.ts +2 -2
  19. package/dist/cli/chat.d.ts.map +1 -1
  20. package/dist/cli/chat.js +12 -24
  21. package/dist/cli/chat.js.map +1 -1
  22. package/dist/cli/client-for.d.ts +6 -0
  23. package/dist/cli/client-for.d.ts.map +1 -0
  24. package/dist/cli/client-for.js +7 -0
  25. package/dist/cli/client-for.js.map +1 -0
  26. package/dist/cli/connected.d.ts +4 -4
  27. package/dist/cli/connected.d.ts.map +1 -1
  28. package/dist/cli/connected.js +2 -2
  29. package/dist/cli/connected.js.map +1 -1
  30. package/dist/cli/dotenv.d.ts +24 -0
  31. package/dist/cli/dotenv.d.ts.map +1 -0
  32. package/dist/cli/dotenv.js +69 -0
  33. package/dist/cli/dotenv.js.map +1 -0
  34. package/dist/cli/env.d.ts +21 -37
  35. package/dist/cli/env.d.ts.map +1 -1
  36. package/dist/cli/env.js +35 -68
  37. package/dist/cli/env.js.map +1 -1
  38. package/dist/cli/eval.d.ts +2 -1
  39. package/dist/cli/eval.d.ts.map +1 -1
  40. package/dist/cli/eval.js +5 -4
  41. package/dist/cli/eval.js.map +1 -1
  42. package/dist/cli/groups.d.ts.map +1 -1
  43. package/dist/cli/groups.js +0 -1
  44. package/dist/cli/groups.js.map +1 -1
  45. package/dist/cli/index.d.ts.map +1 -1
  46. package/dist/cli/index.js +25 -30
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/cli/lexicon.d.ts +14 -0
  49. package/dist/cli/lexicon.d.ts.map +1 -0
  50. package/dist/cli/lexicon.js +123 -0
  51. package/dist/cli/lexicon.js.map +1 -0
  52. package/dist/cli/line.js +6 -6
  53. package/dist/cli/line.js.map +1 -1
  54. package/dist/cli/linking.d.ts +13 -0
  55. package/dist/cli/linking.d.ts.map +1 -0
  56. package/dist/cli/linking.js +103 -0
  57. package/dist/cli/linking.js.map +1 -0
  58. package/dist/cli/load.js +1 -1
  59. package/dist/cli/load.js.map +1 -1
  60. package/dist/cli/login.d.ts +5 -11
  61. package/dist/cli/login.d.ts.map +1 -1
  62. package/dist/cli/login.js +31 -140
  63. package/dist/cli/login.js.map +1 -1
  64. package/dist/cli/memory-policy.d.ts +9 -0
  65. package/dist/cli/memory-policy.d.ts.map +1 -0
  66. package/dist/cli/memory-policy.js +79 -0
  67. package/dist/cli/memory-policy.js.map +1 -0
  68. package/dist/cli/memory.d.ts.map +1 -1
  69. package/dist/cli/memory.js +9 -1
  70. package/dist/cli/memory.js.map +1 -1
  71. package/dist/cli/pipeline.d.ts +2 -0
  72. package/dist/cli/pipeline.d.ts.map +1 -1
  73. package/dist/cli/pipeline.js +18 -76
  74. package/dist/cli/pipeline.js.map +1 -1
  75. package/dist/cli/serve/server.d.ts +1 -1
  76. package/dist/cli/serve/server.d.ts.map +1 -1
  77. package/dist/cli/serve/server.js +3 -2
  78. package/dist/cli/serve/server.js.map +1 -1
  79. package/dist/cli/serve/sidecar.js +1 -1
  80. package/dist/cli/serve/sidecar.js.map +1 -1
  81. package/dist/cli/serve.d.ts +1 -1
  82. package/dist/cli/serve.d.ts.map +1 -1
  83. package/dist/cli/serve.js +5 -5
  84. package/dist/cli/serve.js.map +1 -1
  85. package/dist/cli/signed-in.d.ts +36 -0
  86. package/dist/cli/signed-in.d.ts.map +1 -0
  87. package/dist/cli/signed-in.js +60 -0
  88. package/dist/cli/signed-in.js.map +1 -0
  89. package/dist/cli/simulate.d.ts.map +1 -1
  90. package/dist/cli/simulate.js +7 -6
  91. package/dist/cli/simulate.js.map +1 -1
  92. package/dist/cli/{run-console.d.ts → start-console.d.ts} +2 -2
  93. package/dist/cli/start-console.d.ts.map +1 -0
  94. package/dist/cli/{run-console.js → start-console.js} +3 -3
  95. package/dist/cli/start-console.js.map +1 -0
  96. package/dist/cli/{run-screens.d.ts → start-screens.d.ts} +2 -2
  97. package/dist/cli/start-screens.d.ts.map +1 -0
  98. package/dist/cli/{run-screens.js → start-screens.js} +3 -3
  99. package/dist/cli/start-screens.js.map +1 -0
  100. package/dist/cli/{run.d.ts → start.d.ts} +3 -3
  101. package/dist/cli/start.d.ts.map +1 -0
  102. package/dist/cli/{run.js → start.js} +31 -35
  103. package/dist/cli/start.js.map +1 -0
  104. package/dist/cli/supervise.d.ts +1 -1
  105. package/dist/cli/supervise.d.ts.map +1 -1
  106. package/dist/cli/supervise.js +1 -1
  107. package/dist/cli/supervise.js.map +1 -1
  108. package/dist/cli/testing/gateway.d.ts +3 -0
  109. package/dist/cli/testing/gateway.d.ts.map +1 -1
  110. package/dist/cli/testing/gateway.js +2 -4
  111. package/dist/cli/testing/gateway.js.map +1 -1
  112. package/dist/cli/tuned.d.ts +8 -0
  113. package/dist/cli/tuned.d.ts.map +1 -0
  114. package/dist/cli/tuned.js +66 -0
  115. package/dist/cli/tuned.js.map +1 -0
  116. package/dist/cli/ui/chatting.d.ts +1 -1
  117. package/dist/cli/ui/chatting.d.ts.map +1 -1
  118. package/dist/cli/ui/chatting.js +11 -10
  119. package/dist/cli/ui/chatting.js.map +1 -1
  120. package/dist/cli/ui/console/assets/{index-DhcpHPdk.js → index--8qx-Pi4.js} +16 -12
  121. package/dist/cli/ui/console/assets/index-DmN15Axn.css +1 -0
  122. package/dist/cli/ui/console/index.html +2 -2
  123. package/dist/cli/ui/doors.d.ts +2 -2
  124. package/dist/cli/ui/doors.d.ts.map +1 -1
  125. package/dist/cli/ui/doors.js +2 -2
  126. package/dist/cli/ui/doors.js.map +1 -1
  127. package/dist/cli/ui/drifting.d.ts +1 -1
  128. package/dist/cli/ui/drifting.js +1 -1
  129. package/dist/cli/ui/knowing.d.ts +1 -1
  130. package/dist/cli/ui/knowing.js +3 -3
  131. package/dist/cli/ui/knowing.js.map +1 -1
  132. package/dist/cli/ui/promoting.d.ts +1 -1
  133. package/dist/cli/ui/promoting.js +1 -1
  134. package/dist/cli/ui/remembering.d.ts +1 -1
  135. package/dist/cli/ui/remembering.js +3 -3
  136. package/dist/cli/ui/remembering.js.map +1 -1
  137. package/dist/cli/ui/reproducing.d.ts +1 -1
  138. package/dist/cli/ui/reproducing.js +1 -1
  139. package/dist/cli/ui/simulating.d.ts +1 -1
  140. package/dist/cli/ui/simulating.js +4 -4
  141. package/dist/cli/ui/simulating.js.map +1 -1
  142. package/dist/cli/ui/testing.d.ts +1 -1
  143. package/dist/cli/ui/testing.js +3 -3
  144. package/dist/cli/ui/testing.js.map +1 -1
  145. package/dist/cli/whoami.d.ts +6 -2
  146. package/dist/cli/whoami.d.ts.map +1 -1
  147. package/dist/cli/whoami.js +6 -5
  148. package/dist/cli/whoami.js.map +1 -1
  149. package/dist/cli/world.d.ts +14 -24
  150. package/dist/cli/world.d.ts.map +1 -1
  151. package/dist/cli/world.js +21 -36
  152. package/dist/cli/world.js.map +1 -1
  153. package/dist/client/agent.d.ts +1 -1
  154. package/dist/client/agent.js +2 -2
  155. package/dist/client/agent.js.map +1 -1
  156. package/dist/client/client.d.ts +9 -1
  157. package/dist/client/client.d.ts.map +1 -1
  158. package/dist/client/client.js +5 -2
  159. package/dist/client/client.js.map +1 -1
  160. package/dist/client/connection.d.ts +3 -0
  161. package/dist/client/connection.d.ts.map +1 -1
  162. package/dist/client/connection.js +2 -1
  163. package/dist/client/connection.js.map +1 -1
  164. package/dist/client/index.d.ts +1 -0
  165. package/dist/client/index.d.ts.map +1 -1
  166. package/dist/client/observe.d.ts +3 -0
  167. package/dist/client/observe.d.ts.map +1 -1
  168. package/dist/client/observe.js +2 -1
  169. package/dist/client/observe.js.map +1 -1
  170. package/dist/client/signed.d.ts +15 -0
  171. package/dist/client/signed.d.ts.map +1 -0
  172. package/dist/client/signed.js +19 -0
  173. package/dist/client/signed.js.map +1 -0
  174. package/dist/views/render.d.ts +1 -1
  175. package/dist/views/render.js +1 -1
  176. package/package.json +2 -2
  177. package/dist/cli/config.d.ts +0 -16
  178. package/dist/cli/config.d.ts.map +0 -1
  179. package/dist/cli/config.js +0 -125
  180. package/dist/cli/config.js.map +0 -1
  181. package/dist/cli/credentials.d.ts +0 -41
  182. package/dist/cli/credentials.d.ts.map +0 -1
  183. package/dist/cli/credentials.js +0 -98
  184. package/dist/cli/credentials.js.map +0 -1
  185. package/dist/cli/gateway.d.ts +0 -12
  186. package/dist/cli/gateway.d.ts.map +0 -1
  187. package/dist/cli/gateway.js +0 -67
  188. package/dist/cli/gateway.js.map +0 -1
  189. package/dist/cli/keys.d.ts +0 -28
  190. package/dist/cli/keys.d.ts.map +0 -1
  191. package/dist/cli/keys.js +0 -137
  192. package/dist/cli/keys.js.map +0 -1
  193. package/dist/cli/profiles.d.ts +0 -122
  194. package/dist/cli/profiles.d.ts.map +0 -1
  195. package/dist/cli/profiles.js +0 -312
  196. package/dist/cli/profiles.js.map +0 -1
  197. package/dist/cli/run-console.d.ts.map +0 -1
  198. package/dist/cli/run-console.js.map +0 -1
  199. package/dist/cli/run-screens.d.ts.map +0 -1
  200. package/dist/cli/run-screens.js.map +0 -1
  201. package/dist/cli/run.d.ts.map +0 -1
  202. package/dist/cli/run.js.map +0 -1
  203. package/dist/cli/ui/console/assets/index-iylvEP0_.css +0 -1
package/README.md CHANGED
@@ -57,22 +57,29 @@ on a laptop in one sitting. To read this code or run the two examples, clone ins
57
57
  ```
58
58
  pnpm install nothing to build: the checkout runs from its sources
59
59
  cd examples/clinica-norte
60
+ pnpm exec pinecall link sign in through a browser, pick the org: your key, in ./.env
60
61
  pnpm exec pinecall chat the agent in this terminal, and a prompt against it
61
62
  pnpm exec pinecall prompt --state test/prompts/states.json the exact prompt a state produces
62
- pnpm exec pinecall run the app: the process you deploy
63
- pnpm exec pinecall run --serve the same, and its console on http://localhost:4100
63
+ pnpm exec pinecall start the app: the process you deploy
64
+ pnpm exec pinecall start --serve the same, and its console on http://localhost:4100
64
65
  pnpm exec pinecall serve that console alone: your sandbox, on this machine
65
66
  pnpm exec pinecall knowledge push ./knowledge/docs to the gateway, under the agent's name
66
67
  pnpm exec pinecall test ring 1: the goldens, through the app in this process
67
68
  ```
68
69
 
69
70
  Two consoles, one per world. What you are running is in the sandbox and is watched on your own
70
- machine — `pinecall serve` forwards every request to the gateway with the terminal's key, so there
71
+ machine — `pinecall serve` forwards every request to the gateway with the project's key, so there
71
72
  is nothing to sign in to. Production is watched on the gateway's own page, which shows production
72
73
  and nothing else. [docs/the-cli.md](docs/the-cli.md#serve).
73
74
 
74
- A tenant that installed `pinecall` from npm has it on the PATH and writes `pinecall run`. A
75
- repository of several agents keeps each in `agents/<name>.tsx`, and one `pinecall run` at its root
75
+ Every verb reads `PINECALL_KEY` (and `PINECALL_URL`, when the gateway is not the cloud) from the
76
+ environment, else from the project's `.env`, which `pinecall link` wrote; each is the sandbox until
77
+ `--prod` says production, for a person whose org lets them act there. On a server the agent runs
78
+ on a server's token from the console's Tokens screen, as `pinecall start --prod` or mounted inside
79
+ your own Node app — [docs/production.md](docs/production.md).
80
+
81
+ A tenant that installed `pinecall` from npm has it on the PATH and writes `pinecall start`. A
82
+ repository of several agents keeps each in `agents/<name>.tsx`, and one `pinecall start` at its root
76
83
  holds them all — [docs/writing-an-agent.md](docs/writing-an-agent.md#several-agents-in-one-project).
77
84
 
78
85
  Working on the framework itself:
@@ -131,7 +138,8 @@ means editing a list on purpose, which is the point.
131
138
  | [docs/testing-an-agent.md](docs/testing-an-agent.md) | the five rings: unit tests, goldens, personas, one call replayed, the score every call gets |
132
139
  | [docs/testing-memory-and-knowledge.md](docs/testing-memory-and-knowledge.md) | memory's own goldens, the index's, and why a call has no retrieval score |
133
140
  | [docs/the-cli.md](docs/the-cli.md) | every verb, what it needs, and where its key comes from — one agent, or a project of several |
134
- | [docs/worlds-and-teams.md](docs/worlds-and-teams.md) | from the sign-up to the deploy: the two worlds, what is yours and what is the org's, the team and its seats |
141
+ | [docs/worlds-and-teams.md](docs/worlds-and-teams.md) | one key per person, the production switch, the two worlds, a team from the invitation to the rollback |
142
+ | [docs/production.md](docs/production.md) | running the agent on your own server: the server's token, the two ways, the release push, changes with `--prod` |
135
143
  | [CHANGELOG.md](CHANGELOG.md) · [CLAUDE.md](CLAUDE.md) | what changed · the working agreement |
136
144
 
137
145
  ## The wire
@@ -0,0 +1,6 @@
1
+ /** `pinecall agent pull | push`: a corner's settings as a file, for whoever keeps them in git and CI. */
2
+ import type { Typed } from "./agent.js";
3
+ import { type Door } from "./testing/gateway.js";
4
+ /** The two file verbs, dispatched by `pinecall agent`. */
5
+ export declare function filesRun(door: Door, agent: string, verb: "pull" | "push", rest: string[], values: Typed, out: NodeJS.WritableStream, err: NodeJS.WritableStream): Promise<number>;
6
+ //# sourceMappingURL=agent-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-files.d.ts","sourceRoot":"","sources":["../../src/cli/agent-files.ts"],"names":[],"mappings":"AAAA,yGAAyG;AAOzG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAWxD,0DAA0D;AAC1D,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,KAAK,EACb,GAAG,EAAE,MAAM,CAAC,cAAc,EAC1B,GAAG,EAAE,MAAM,CAAC,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CAGjB"}
@@ -0,0 +1,40 @@
1
+ /** `pinecall agent pull | push`: a corner's settings as a file, for whoever keeps them in git and CI. */
2
+ import { readFile } from "node:fs/promises";
3
+ import { readSettings, settingsPath } from "./agent-lines.js";
4
+ import { asked } from "./testing/gateway.js";
5
+ /** The two file verbs, dispatched by `pinecall agent`. */
6
+ export async function filesRun(door, agent, verb, rest, values, out, err) {
7
+ if (verb === "pull")
8
+ return pull(door, agent, values.team === true, out, err);
9
+ return push(door, agent, rest[0], values.team === true, out, err);
10
+ }
11
+ // The team's corner unless --team is absent AND the key has one of its own with a row: a machine
12
+ // key pulls the org's own, which is what a CI job keeps in the repository.
13
+ async function pull(door, agent, team, out, err) {
14
+ const answer = await readSettings(door, agent);
15
+ const row = team ? answer.team : (answer.yours ?? answer.team);
16
+ if (row === null) {
17
+ err.write(`nothing set for ${agent} in ${team ? "the team's" : "your"} corner of ${answer.world}\n`);
18
+ return 1;
19
+ }
20
+ const pulled = { agent, world: answer.world, holder: row.holder, version: row.version, config: row.config };
21
+ out.write(`${JSON.stringify(pulled, null, 2)}\n`);
22
+ return 0;
23
+ }
24
+ // A push carries no if_version: CI is applying a file, and what stands is what the file says.
25
+ async function push(door, agent, file, team, out, err) {
26
+ if (file === undefined) {
27
+ err.write("push takes the file `pinecall agent pull` wrote\n");
28
+ return 2;
29
+ }
30
+ const read = JSON.parse(await readFile(file, "utf8"));
31
+ const config = read.config ?? read;
32
+ const answer = await asked(door, settingsPath(agent), {
33
+ method: "PUT",
34
+ body: { config, if_version: null, note: `pushed from ${file}`, team },
35
+ });
36
+ const row = team ? answer.team : (answer.yours ?? answer.team);
37
+ out.write(`${agent} · ${answer.world} · ${team ? "the team's corner" : "your corner"} v${row?.version ?? "?"} from ${file}\n`);
38
+ return 0;
39
+ }
40
+ //# sourceMappingURL=agent-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-files.js","sourceRoot":"","sources":["../../src/cli/agent-files.ts"],"names":[],"mappings":"AAAA,yGAAyG;AAEzG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,KAAK,EAAa,MAAM,sBAAsB,CAAC;AAWxD,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAU,EACV,KAAa,EACb,IAAqB,EACrB,IAAc,EACd,MAAa,EACb,GAA0B,EAC1B,GAA0B;IAE1B,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,iGAAiG;AACjG,2EAA2E;AAC3E,KAAK,UAAU,IAAI,CAAC,IAAU,EAAE,KAAa,EAAE,IAAa,EAAE,GAA0B,EAAE,GAA0B;IAClH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,GAAG,CAAC,KAAK,CAAC,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,cAAc,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QACrG,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAW,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACpH,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,8FAA8F;AAC9F,KAAK,UAAU,IAAI,CAAC,IAAU,EAAE,KAAa,EAAE,IAAwB,EAAE,IAAa,EAAE,GAA0B,EAAE,GAA0B;IAC5I,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC/D,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAoB,CAAC;IACzE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAK,IAAmB,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAe,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE;QAClE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,IAAI,EAAE,EAAE,IAAI,EAAE;KACtE,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/D,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,MAAM,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,KAAK,GAAG,EAAE,OAAO,IAAI,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC;IAC/H,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** How `pinecall agent` says the three corners on one page, and the door it reads them from. */
2
+ import type { TuningAnswer, TuningBody, TuningRow } from "@pinecall/protocol";
3
+ import { type Door } from "./testing/gateway.js";
4
+ /** The settings door of one agent, spelled once for every verb that knocks at it. */
5
+ export declare function settingsPath(agent: string): string;
6
+ /** The three corners as this key sees them: its own, the team's, production's. */
7
+ export declare function readSettings(door: Door, agent: string): Promise<TuningAnswer>;
8
+ /** The fields on the page, in the order a person reads them, under the names a person types. */
9
+ export declare const FIELDS: readonly ["voice", "tts", "tts-model", "stt", "llm", "greeting", "hangup", "turn", "memory", "knowledge"];
10
+ export type Field = (typeof FIELDS)[number];
11
+ /** The name a person types, as the wire spells it. */
12
+ export declare const WIRE: Record<Field, keyof TuningBody>;
13
+ /** One field of one config, as a cell of the page; undefined when the config does not set it. */
14
+ export declare function shown(config: TuningBody, field: Field): string | undefined;
15
+ /** One kept version on one line: the number, who, when, and why. */
16
+ export declare function versionLine(row: TuningRow): string;
17
+ /**
18
+ * The page: the agent and the world, the three corners as columns, a row per field, and under
19
+ * them which version each corner is at. A corner that set nothing reads as what it falls back
20
+ * to — `(team's)` in your column — because that is what a session built there runs.
21
+ */
22
+ export declare function linesOf(agent: string, answer: TuningAnswer): string[];
23
+ //# sourceMappingURL=agent-lines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-lines.d.ts","sourceRoot":"","sources":["../../src/cli/agent-lines.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG9E,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAExD,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,kFAAkF;AAClF,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAEnF;AAED,gGAAgG;AAChG,eAAO,MAAM,MAAM,YAAI,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAChI,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5C,sDAAsD;AACtD,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,UAAU,CAWhD,CAAC;AAOF,iGAAiG;AACjG,wBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAiC1E;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAqBrE"}
@@ -0,0 +1,109 @@
1
+ /** How `pinecall agent` says the three corners on one page, and the door it reads them from. */
2
+ import { dayAndTime } from "./knowledge.js";
3
+ import { asked } from "./testing/gateway.js";
4
+ /** The settings door of one agent, spelled once for every verb that knocks at it. */
5
+ export function settingsPath(agent) {
6
+ return `/v1/agents/${encodeURIComponent(agent)}/settings`;
7
+ }
8
+ /** The three corners as this key sees them: its own, the team's, production's. */
9
+ export async function readSettings(door, agent) {
10
+ return await asked(door, settingsPath(agent));
11
+ }
12
+ /** The fields on the page, in the order a person reads them, under the names a person types. */
13
+ export const FIELDS = ["voice", "tts", "tts-model", "stt", "llm", "greeting", "hangup", "turn", "memory", "knowledge"];
14
+ /** The name a person types, as the wire spells it. */
15
+ export const WIRE = {
16
+ voice: "voice",
17
+ tts: "tts",
18
+ "tts-model": "tts_model",
19
+ stt: "stt",
20
+ llm: "llm",
21
+ greeting: "greeting",
22
+ hangup: "hangup",
23
+ turn: "turn",
24
+ memory: "memory",
25
+ knowledge: "knowledge",
26
+ };
27
+ // A cell is one line, however the field is shaped: the words of an opening in quotes, a turn's
28
+ // two numbers, a memory policy as two counts, the bases by name. Long words are cut, because a
29
+ // page of three columns has to stay a page.
30
+ const A_CELL = 40;
31
+ /** One field of one config, as a cell of the page; undefined when the config does not set it. */
32
+ export function shown(config, field) {
33
+ // The wire leaves a field out or sends null for "not set": both read as nothing here.
34
+ if (field === "greeting") {
35
+ const greeting = config.greeting ?? undefined;
36
+ if (greeting === undefined)
37
+ return undefined;
38
+ const say = greeting.say ?? undefined;
39
+ return say !== undefined ? `"${say}"` : `reply: ${greeting.reply ?? ""}`;
40
+ }
41
+ if (field === "hangup") {
42
+ const hangup = config.hangup ?? undefined;
43
+ if (hangup === undefined)
44
+ return undefined;
45
+ return hangup.when === "" || hangup.when === null || hangup.when === undefined ? "may hang up" : `when ${hangup.when}`;
46
+ }
47
+ if (field === "turn") {
48
+ const turn = config.turn ?? undefined;
49
+ if (turn === undefined)
50
+ return undefined;
51
+ const said = [];
52
+ if (turn.endpointing_ms !== undefined && turn.endpointing_ms !== null)
53
+ said.push(`endpointing ${turn.endpointing_ms} ms`);
54
+ if (turn.min_interruption_words !== undefined && turn.min_interruption_words !== null)
55
+ said.push(`interrupt at ${turn.min_interruption_words} words`);
56
+ return said.join(" · ");
57
+ }
58
+ if (field === "memory") {
59
+ const memory = config.memory ?? undefined;
60
+ if (memory === undefined)
61
+ return undefined;
62
+ return `remember ${memory.remember?.length ?? 0} · forget ${memory.forget?.length ?? 0}`;
63
+ }
64
+ if (field === "knowledge") {
65
+ const bases = config.knowledge ?? undefined;
66
+ if (bases === undefined || bases.length === 0)
67
+ return undefined;
68
+ return bases.map((one) => `${one.base}${one.k === undefined || one.k === null ? "" : ` (k ${one.k})`}`).join(" · ");
69
+ }
70
+ const value = config[WIRE[field]];
71
+ return typeof value === "string" ? value : undefined;
72
+ }
73
+ /** One kept version on one line: the number, who, when, and why. */
74
+ export function versionLine(row) {
75
+ const said = [`v${row.version}`, row.author, dayAndTime(row.set_at)];
76
+ if (row.note !== null)
77
+ said.push(`"${row.note}"`);
78
+ return said.join(" · ");
79
+ }
80
+ /**
81
+ * The page: the agent and the world, the three corners as columns, a row per field, and under
82
+ * them which version each corner is at. A corner that set nothing reads as what it falls back
83
+ * to — `(team's)` in your column — because that is what a session built there runs.
84
+ */
85
+ export function linesOf(agent, answer) {
86
+ const corners = [
87
+ { name: "yours", row: answer.yours, fallsTo: "(team's)" },
88
+ { name: "team", row: answer.team, fallsTo: "—" },
89
+ { name: "production", row: answer.production, fallsTo: "—" },
90
+ ];
91
+ const cell = (corner, field) => {
92
+ if (corner.row === null)
93
+ return corner.fallsTo;
94
+ const value = shown(corner.row.config, field);
95
+ if (value === undefined)
96
+ return "—";
97
+ return value.length > A_CELL ? `${value.slice(0, A_CELL - 1)}…` : value;
98
+ };
99
+ const widths = corners.map((corner) => Math.max(corner.name.length, ...FIELDS.map((field) => cell(corner, field).length)) + 2);
100
+ const lines = [`${agent} · ${answer.world}`, ""];
101
+ lines.push(` ${"".padEnd(14)}${corners.map((corner, at) => corner.name.padEnd(widths[at])).join("")}`.trimEnd());
102
+ for (const field of FIELDS) {
103
+ lines.push(` ${field.replace("-", " ").padEnd(14)}${corners.map((corner, at) => cell(corner, field).padEnd(widths[at])).join("")}`.trimEnd());
104
+ }
105
+ lines.push("");
106
+ lines.push(` ${corners.map((corner) => `${corner.name}: ${corner.row === null ? "nothing set" : versionLine(corner.row)}`).join(" · ")}`);
107
+ return lines;
108
+ }
109
+ //# sourceMappingURL=agent-lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-lines.js","sourceRoot":"","sources":["../../src/cli/agent-lines.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** `pinecall agent history | diff | rollback`: the versions a corner kept, and one of them back. */
2
+ import type { TuningBody, TuningRow } from "@pinecall/protocol";
3
+ import { type Field } from "./agent-lines.js";
4
+ import type { Typed } from "./agent.js";
5
+ import { type Door } from "./testing/gateway.js";
6
+ /** The three version verbs, dispatched by `pinecall agent`. */
7
+ export declare function versionsRun(door: Door, agent: string, verb: "history" | "diff" | "rollback", rest: string[], values: Typed, out: NodeJS.WritableStream, err: NodeJS.WritableStream): Promise<number>;
8
+ /** The fields set differently between two configs, each as `field before → after`. */
9
+ export declare function changes(before: TuningBody, after: TuningBody, lead: string, joined?: string): string;
10
+ /** Whether a kept row sets this field at all, for the pages that draw a row. */
11
+ export declare function sets(row: TuningRow, field: Field): boolean;
12
+ //# sourceMappingURL=agent-versions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-versions.d.ts","sourceRoot":"","sources":["../../src/cli/agent-versions.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAEpG,OAAO,KAAK,EAAgB,UAAU,EAA6B,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzG,OAAO,EAAqD,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAExD,+DAA+D;AAC/D,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,UAAU,EACrC,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,KAAK,EACb,GAAG,EAAE,MAAM,CAAC,cAAc,EAC1B,GAAG,EAAE,MAAM,CAAC,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CAIjB;AA+CD,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAQ,GAAG,MAAM,CASnG;AAED,gFAAgF;AAChF,wBAAgB,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,70 @@
1
+ /** `pinecall agent history | diff | rollback`: the versions a corner kept, and one of them back. */
2
+ import { FIELDS, linesOf, settingsPath, shown, versionLine } from "./agent-lines.js";
3
+ import { asked } from "./testing/gateway.js";
4
+ /** The three version verbs, dispatched by `pinecall agent`. */
5
+ export async function versionsRun(door, agent, verb, rest, values, out, err) {
6
+ if (verb === "history")
7
+ return history(door, agent, values.team === true, out);
8
+ if (verb === "diff")
9
+ return diff(door, agent, values.against, out, err);
10
+ return rollback(door, agent, rest[0], values.team === true, out, err);
11
+ }
12
+ async function history(door, agent, team, out) {
13
+ const kept = await asked(door, `${settingsPath(agent)}/history?team=${team}`);
14
+ out.write(`${agent} · ${kept.world} · ${kept.holder === "" ? "the org's own corner" : `corner ${kept.holder}`}\n`);
15
+ if (kept.rows.length === 0) {
16
+ out.write(" nothing set yet\n");
17
+ return 0;
18
+ }
19
+ // Each version against the one before it, so a line says what that save changed and not the
20
+ // whole set again; the oldest is against nothing, and reads as what it set.
21
+ kept.rows.forEach((row, at) => {
22
+ const older = kept.rows[at + 1] ?? null;
23
+ out.write(` ${versionLine(row)}${changes(older?.config ?? {}, row.config, " ")}\n`);
24
+ });
25
+ return 0;
26
+ }
27
+ async function diff(door, agent, against, out, err) {
28
+ const world = against ?? "production";
29
+ if (world !== "team" && world !== "production") {
30
+ err.write("--against takes team or production\n");
31
+ return 2;
32
+ }
33
+ const said = await asked(door, `${settingsPath(agent)}/diff?against=${world}`);
34
+ const ours = said.ours === null ? "nothing set" : `${said.ours.holder === "" ? "team" : "yours"} v${said.ours.version}`;
35
+ const theirs = said.theirs === null ? "nothing set" : `v${said.theirs.version}`;
36
+ out.write(`${agent} · ${ours} vs ${world} ${theirs}\n`);
37
+ if (said.changed.length === 0) {
38
+ out.write(" the same\n");
39
+ return 0;
40
+ }
41
+ out.write(`${changes(said.theirs?.config ?? {}, said.ours?.config ?? {}, " ", "\n")}\n`);
42
+ return 0;
43
+ }
44
+ async function rollback(door, agent, version, team, out, err) {
45
+ const wanted = Number(version);
46
+ if (version === undefined || !Number.isInteger(wanted) || wanted < 1) {
47
+ err.write("rollback takes the version to bring back: `pinecall agent history` lists them\n");
48
+ return 2;
49
+ }
50
+ const answer = await asked(door, `${settingsPath(agent)}/rollback`, { method: "POST", body: { version: wanted, team } });
51
+ out.write(`${linesOf(agent, answer).join("\n")}\n`);
52
+ return 0;
53
+ }
54
+ /** The fields set differently between two configs, each as `field before → after`. */
55
+ export function changes(before, after, lead, joined = " · ") {
56
+ const said = [];
57
+ for (const field of FIELDS) {
58
+ const was = shown(before, field);
59
+ const is = shown(after, field);
60
+ if (was === is)
61
+ continue;
62
+ said.push(`${field.replace("-", " ")} ${was ?? "—"} → ${is ?? "—"}`);
63
+ }
64
+ return said.length === 0 ? "" : `${lead}${said.join(joined === "\n" ? `\n${lead}` : joined)}`;
65
+ }
66
+ /** Whether a kept row sets this field at all, for the pages that draw a row. */
67
+ export function sets(row, field) {
68
+ return shown(row.config, field) !== undefined;
69
+ }
70
+ //# sourceMappingURL=agent-versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-versions.js","sourceRoot":"","sources":["../../src/cli/agent-versions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /** `pinecall agent`: what the org set over the class — yours, the team's, production's — and setting it. */
2
+ import { parseArgs } from "node:util";
3
+ import type { TuningBody } from "@pinecall/protocol";
4
+ import type { Group } from "./groups.js";
5
+ export declare const group: Group;
6
+ /** What the verb can be told besides the argv: where to print, and which environment. Tests only. */
7
+ export interface Setting {
8
+ out?: NodeJS.WritableStream;
9
+ err?: NodeJS.WritableStream;
10
+ env?: NodeJS.ProcessEnv;
11
+ }
12
+ /** Every flag the sub-verbs take, declared once: parseArgs is strict, and one table is one seam. */
13
+ export declare const OPTIONS: {
14
+ readonly agent: {
15
+ readonly type: "string";
16
+ };
17
+ readonly json: {
18
+ readonly type: "boolean";
19
+ readonly default: false;
20
+ };
21
+ readonly team: {
22
+ readonly type: "boolean";
23
+ readonly default: false;
24
+ };
25
+ readonly note: {
26
+ readonly type: "string";
27
+ };
28
+ readonly voice: {
29
+ readonly type: "string";
30
+ };
31
+ readonly tts: {
32
+ readonly type: "string";
33
+ };
34
+ readonly "tts-model": {
35
+ readonly type: "string";
36
+ };
37
+ readonly stt: {
38
+ readonly type: "string";
39
+ };
40
+ readonly llm: {
41
+ readonly type: "string";
42
+ };
43
+ readonly greeting: {
44
+ readonly type: "string";
45
+ };
46
+ readonly reply: {
47
+ readonly type: "string";
48
+ };
49
+ readonly hangup: {
50
+ readonly type: "string";
51
+ };
52
+ readonly "endpointing-ms": {
53
+ readonly type: "string";
54
+ };
55
+ readonly "min-interruption-words": {
56
+ readonly type: "string";
57
+ };
58
+ readonly remember: {
59
+ readonly type: "string";
60
+ readonly multiple: true;
61
+ };
62
+ readonly forget: {
63
+ readonly type: "string";
64
+ readonly multiple: true;
65
+ };
66
+ readonly against: {
67
+ readonly type: "string";
68
+ };
69
+ };
70
+ export type Typed = ReturnType<typeof parseArgs<{
71
+ options: typeof OPTIONS;
72
+ allowPositionals: true;
73
+ }>>["values"];
74
+ export declare function run(argv: string[], how?: Setting): Promise<number>;
75
+ /** What this command line set, under the wire's names, over what the corner's row already says. */
76
+ export declare function typed(values: Typed, standing: TuningBody): Partial<TuningBody>;
77
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/cli/agent.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,EAA2B,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAM9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgBzC,eAAO,MAAM,KAAK,EAAE,KA2BnB,CAAC;AAEF,qGAAqG;AACrG,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,oGAAoG;AACpG,eAAO,MAAM,OAAO;aAClB,KAAK;iBAAI,IAAI,EAAE,QAAQ;;aACvB,IAAI;iBAAI,IAAI,EAAE,SAAS;iBAAE,OAAO;;aAChC,IAAI;iBAAI,IAAI,EAAE,SAAS;iBAAE,OAAO;;aAChC,IAAI;iBAAI,IAAI,EAAE,QAAQ;;aACtB,KAAK;iBAAI,IAAI,EAAE,QAAQ;;aACvB,GAAG;iBAAI,IAAI,EAAE,QAAQ;;aACrB,WAAW;iBAAI,IAAI,EAAE,QAAQ;;aAC7B,GAAG;iBAAI,IAAI,EAAE,QAAQ;;aACrB,GAAG;iBAAI,IAAI,EAAE,QAAQ;;aACrB,QAAQ;iBAAI,IAAI,EAAE,QAAQ;;aAC1B,KAAK;iBAAI,IAAI,EAAE,QAAQ;;aACvB,MAAM;iBAAI,IAAI,EAAE,QAAQ;;aACxB,gBAAgB;iBAAI,IAAI,EAAE,QAAQ;;aAClC,wBAAwB;iBAAI,IAAI,EAAE,QAAQ;;aAC1C,QAAQ;iBAAI,IAAI,EAAE,QAAQ;iBAAE,QAAQ;;aACpC,MAAM;iBAAI,IAAI,EAAE,QAAQ;iBAAE,QAAQ;;aAClC,OAAO;iBAAI,IAAI,EAAE,QAAQ;;CACjB,CAAC;AAEX,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,OAAO,CAAC;IAAC,gBAAgB,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEhH,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,OAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC5E;AA2CD,mGAAmG;AACnG,wBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAuB9E"}
@@ -0,0 +1,192 @@
1
+ /** `pinecall agent`: what the org set over the class — yours, the team's, production's — and setting it. */
2
+ import { parseArgs } from "node:util";
3
+ import { FIELDS, linesOf, readSettings, settingsPath, WIRE } from "./agent-lines.js";
4
+ import { filesRun } from "./agent-files.js";
5
+ import { versionsRun } from "./agent-versions.js";
6
+ import { theDoor } from "./env.js";
7
+ import { agentOfThisDirectory, notASlug } from "./load.js";
8
+ import { asked } from "./testing/gateway.js";
9
+ import { refusal } from "./whoami.js";
10
+ const USAGE = [
11
+ "usage: pinecall agent [--agent <slug>] [--json]",
12
+ " pinecall agent list",
13
+ " pinecall agent set [--voice x] [--tts x] [--tts-model x] [--stt x] [--llm x] [--greeting '…' | --reply '…']",
14
+ " [--hangup '…'] [--endpointing-ms n] [--min-interruption-words n]",
15
+ " [--remember '…' …] [--forget '…' …] [--team] [--note '…']",
16
+ " pinecall agent clear [voice|tts|tts-model|stt|llm|greeting|hangup|turn|memory|knowledge …] [--team]",
17
+ " pinecall agent history [--team] · diff [--against team|production] · rollback <version> [--team]",
18
+ " pinecall agent pull [--team] · push <file> [--team]",
19
+ ].join("\n");
20
+ export const group = {
21
+ purpose: "what the org set over the class — yours, the team's, production's — and setting it",
22
+ usage: `${USAGE}
23
+
24
+ With nothing after it: the agent's settings as your key sees them, three corners side by side —
25
+ your own sandbox corner, the team's, and production's — a row per field, and which version each
26
+ corner is at. A corner that set nothing reads as what it falls back to.
27
+
28
+ set writes a NEW version in your own corner: what you set is yours, and a colleague's next call
29
+ does not hear it. --team writes the org's own corner instead, which every corner falls back to.
30
+ --prod writes production's, if your org lets you act there. The whole set travels with the version it was read at, so two people
31
+ saving at once never write over each other: the second is told where the corner is now. A model
32
+ knob reads three ways — \`--llm anthropic/claude-haiku-4-5\`, \`--llm cartesia\` (a vendor, its own
33
+ model), \`--llm claude-haiku-4-5\` (a model, the vendor in use). --greeting sets the words said as
34
+ the call opens; --reply what the model reads before it finds its own. --remember and --forget
35
+ replace those lists whole. A field nobody names is left as it stands.
36
+
37
+ clear takes fields out of the corner's own row, so what the class declared — or the runtime's
38
+ default — stands for them again; with no name, every field. There is no blank value.
39
+
40
+ history, diff and rollback are the versions: every one kept, who set it and why; this corner
41
+ against the team's or production's; one version back as the next one — with --prod, production's.
42
+ pull prints the corner's config as JSON; push sends a file as the next version, --team to the
43
+ team's corner.
44
+
45
+ list prints the agents this org is holding in your key's world.`,
46
+ run,
47
+ };
48
+ /** Every flag the sub-verbs take, declared once: parseArgs is strict, and one table is one seam. */
49
+ export const OPTIONS = {
50
+ agent: { type: "string" },
51
+ json: { type: "boolean", default: false },
52
+ team: { type: "boolean", default: false },
53
+ note: { type: "string" },
54
+ voice: { type: "string" },
55
+ tts: { type: "string" },
56
+ "tts-model": { type: "string" },
57
+ stt: { type: "string" },
58
+ llm: { type: "string" },
59
+ greeting: { type: "string" },
60
+ reply: { type: "string" },
61
+ hangup: { type: "string" },
62
+ "endpointing-ms": { type: "string" },
63
+ "min-interruption-words": { type: "string" },
64
+ remember: { type: "string", multiple: true },
65
+ forget: { type: "string", multiple: true },
66
+ against: { type: "string" },
67
+ };
68
+ export async function run(argv, how = {}) {
69
+ const out = how.out ?? process.stdout;
70
+ const err = how.err ?? process.stderr;
71
+ const { values, positionals } = parseArgs({ args: argv, allowPositionals: true, options: OPTIONS });
72
+ const door = theDoor(how.env ?? process.env, err);
73
+ if (door === undefined)
74
+ return 2;
75
+ const [verb, ...rest] = positionals;
76
+ try {
77
+ if (verb === "list")
78
+ return await list(door, out);
79
+ const aFile = notASlug(values.agent);
80
+ if (aFile !== undefined) {
81
+ err.write(`${aFile}\n`);
82
+ return 2;
83
+ }
84
+ const agent = values.agent ?? (await agentOfThisDirectory());
85
+ if (agent === null || agent === undefined) {
86
+ err.write(`${USAGE}\n name the agent, or run this beside an agent file\n`);
87
+ return 2;
88
+ }
89
+ if (verb === undefined)
90
+ return said(agent, await readSettings(door, agent), values.json === true, out);
91
+ if (verb === "set")
92
+ return said(agent, await set(door, agent, values), values.json === true, out);
93
+ if (verb === "clear")
94
+ return said(agent, await clear(door, agent, rest, values.team === true), values.json === true, out);
95
+ if (verb === "history" || verb === "diff" || verb === "rollback") {
96
+ return await versionsRun(door, agent, verb, rest, values, out, err);
97
+ }
98
+ if (verb === "pull" || verb === "push")
99
+ return await filesRun(door, agent, verb, rest, values, out, err);
100
+ }
101
+ catch (refused) {
102
+ // The gateway's own sentence: it knows this build's vendors, the corner's version, and which
103
+ // half of the settings a key opens — and every refusal names the one it was.
104
+ err.write(`${refusal(refused)}\n`);
105
+ return 1;
106
+ }
107
+ err.write(`${USAGE}\n`);
108
+ return 2;
109
+ }
110
+ // ── the verbs ───────────────────────────────────────────────────────────────────
111
+ async function list(door, out) {
112
+ const held = await asked(door, "/v1/agents");
113
+ if (held.agents.length === 0) {
114
+ out.write("no agent is held here: `pinecall start` holds one\n");
115
+ return 0;
116
+ }
117
+ for (const one of held.agents) {
118
+ const whose = one.holder === null || one.holder === undefined ? "the org's own" : (one.holder.name ?? one.holder.holder ?? "");
119
+ out.write(`${one.slug} ${one.channels.join(", ") || "no doors"} ${whose}\n`);
120
+ }
121
+ return 0;
122
+ }
123
+ // The door takes the WHOLE set with the version it was read at, so what this command line did
124
+ // not name is read back off the corner's own row and sent again: `set --llm x` must not quietly
125
+ // take the voice out of the row. The corner written is yours, or the team's with --team.
126
+ async function set(door, agent, values) {
127
+ const standing = await readSettings(door, agent);
128
+ const row = values.team === true ? standing.team : standing.yours;
129
+ const config = { ...(row?.config ?? {}), ...typed(values, row?.config ?? {}) };
130
+ return await asked(door, settingsPath(agent), {
131
+ method: "PUT",
132
+ body: { config, if_version: row?.version ?? null, note: values.note ?? null, team: values.team === true },
133
+ });
134
+ }
135
+ async function clear(door, agent, named, team) {
136
+ const unknown = named.filter((name) => !FIELDS.includes(name));
137
+ if (unknown.length > 0)
138
+ throw new Error(`no field called ${unknown.join(", ")}: ${FIELDS.join(" · ")}`);
139
+ const standing = await readSettings(door, agent);
140
+ const row = team ? standing.team : standing.yours;
141
+ const config = named.length === 0 ? {} : { ...(row?.config ?? {}) };
142
+ for (const name of named)
143
+ delete config[WIRE[name]];
144
+ return await asked(door, settingsPath(agent), {
145
+ method: "PUT",
146
+ body: { config, if_version: row?.version ?? null, note: named.length === 0 ? "cleared" : `cleared ${named.join(", ")}`, team },
147
+ });
148
+ }
149
+ /** What this command line set, under the wire's names, over what the corner's row already says. */
150
+ export function typed(values, standing) {
151
+ const wanted = {};
152
+ for (const field of ["voice", "tts", "tts-model", "stt", "llm"]) {
153
+ const value = values[field];
154
+ if (typeof value === "string")
155
+ wanted[WIRE[field]] = value;
156
+ }
157
+ if (values.greeting !== undefined)
158
+ wanted.greeting = { say: values.greeting };
159
+ else if (values.reply !== undefined)
160
+ wanted.greeting = { reply: values.reply };
161
+ if (values.hangup !== undefined)
162
+ wanted.hangup = { when: values.hangup };
163
+ const endpointing = numberOf(values["endpointing-ms"]);
164
+ const words = numberOf(values["min-interruption-words"]);
165
+ if (endpointing !== undefined || words !== undefined) {
166
+ wanted.turn = { ...(standing.turn ?? {}) };
167
+ if (endpointing !== undefined)
168
+ wanted.turn.endpointing_ms = endpointing;
169
+ if (words !== undefined)
170
+ wanted.turn.min_interruption_words = words;
171
+ }
172
+ if (values.remember !== undefined || values.forget !== undefined) {
173
+ wanted.memory = {
174
+ remember: values.remember ?? standing.memory?.remember ?? [],
175
+ forget: values.forget ?? standing.memory?.forget ?? [],
176
+ };
177
+ }
178
+ return wanted;
179
+ }
180
+ function numberOf(said) {
181
+ if (said === undefined)
182
+ return undefined;
183
+ const number = Number(said);
184
+ if (!Number.isInteger(number) || number < 0)
185
+ throw new Error(`${said} is not a whole number`);
186
+ return number;
187
+ }
188
+ function said(agent, answer, asJson, out) {
189
+ out.write(asJson ? `${JSON.stringify(answer)}\n` : `${linesOf(agent, answer).join("\n")}\n`);
190
+ return 0;
191
+ }
192
+ //# sourceMappingURL=agent.js.map