@tpsdev-ai/agent 0.4.2 → 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.
package/dist/bin.js CHANGED
@@ -2,31 +2,57 @@
2
2
  import { AgentRuntime } from "./runtime/agent.js";
3
3
  import { loadAgentConfig } from "./config.js";
4
4
  function usage() {
5
- console.error("Usage: tps-agent run --config <agent.yaml> --message <text>");
5
+ console.error("Usage:");
6
+ console.error(" tps-agent run --config <agent.yaml> --message <text>");
7
+ console.error(" tps-agent start --config <agent.yaml>");
8
+ console.error(" tps-agent health --config <agent.yaml>");
6
9
  process.exit(1);
7
10
  }
11
+ function parseArg(name, args) {
12
+ const idx = args.indexOf(name);
13
+ if (idx >= 0 && idx + 1 < args.length)
14
+ return args[idx + 1];
15
+ return undefined;
16
+ }
17
+ function parseConfig(args) {
18
+ const command = args[0];
19
+ const configPath = parseArg("--config", args);
20
+ return { command, configPath };
21
+ }
8
22
  async function main() {
9
23
  const args = process.argv.slice(2);
10
- const cmd = args[0];
11
- if (cmd !== "run") {
24
+ const { command, configPath } = parseConfig(args);
25
+ if (!command || command === "--help" || command === "-h")
12
26
  usage();
13
- }
14
- const configIdx = args.indexOf("--config");
15
- const msgIdx = args.indexOf("--message");
16
- if (configIdx < 0 || msgIdx < 0) {
27
+ if (!configPath)
17
28
  usage();
18
- }
19
- const configPath = args[configIdx + 1];
20
- const message = args.slice(msgIdx + 1).join(" ");
21
- if (!configPath || !message) {
22
- usage();
23
- }
24
29
  const config = loadAgentConfig(configPath);
25
30
  const runtime = new AgentRuntime(config);
26
- await runtime.runOnce(message);
31
+ switch (command) {
32
+ case "run": {
33
+ const messageIdx = args.indexOf("--message");
34
+ const message = messageIdx >= 0 ? args.slice(messageIdx + 1).join(" ") : process.env.TPS_AGENT_MESSAGE;
35
+ if (!message)
36
+ usage();
37
+ await runtime.runOnce(message);
38
+ return;
39
+ }
40
+ case "start": {
41
+ await runtime.start();
42
+ return;
43
+ }
44
+ case "health": {
45
+ const healthy = runtime.isHealthy();
46
+ process.stdout.write(healthy ? "healthy\n" : "unhealthy\n");
47
+ process.exit(healthy ? 0 : 1);
48
+ return;
49
+ }
50
+ default:
51
+ usage();
52
+ }
27
53
  }
28
54
  main().catch((err) => {
29
- console.error(err?.message || err);
55
+ console.error(String(err?.message || err));
30
56
  process.exit(1);
31
57
  });
32
58
  //# sourceMappingURL=bin.js.map
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,SAAS,KAAK;IACZ,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpB,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,KAAK,EAAE,CAAC;IACV,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzC,IAAI,SAAS,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,KAAK,EAAE,CAAC;IACV,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,KAAK,EAAE,CAAC;IACV,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE;QACH,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACvD,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;IAC3D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CA2BzD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAKxE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE;QACH,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACvD,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC;IAC3D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAgCD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CA4BzD;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAKxE"}
package/dist/config.js CHANGED
@@ -1,9 +1,35 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import yaml from "js-yaml";
3
3
  import { createHash } from "node:crypto";
4
+ function interpolateEnvInString(raw) {
5
+ return raw.replace(/\$\{([A-Z0-9_]+)\}/g, (_match, varName) => {
6
+ const resolved = process.env[varName];
7
+ if (resolved === undefined) {
8
+ throw new Error(`Missing environment variable: ${varName}`);
9
+ }
10
+ return resolved;
11
+ });
12
+ }
13
+ function interpolateEnvVars(value) {
14
+ if (typeof value === "string") {
15
+ return interpolateEnvInString(value);
16
+ }
17
+ if (Array.isArray(value)) {
18
+ return value.map((item) => interpolateEnvVars(item));
19
+ }
20
+ if (value && typeof value === "object") {
21
+ const out = {};
22
+ for (const [k, v] of Object.entries(value)) {
23
+ out[k] = interpolateEnvVars(v);
24
+ }
25
+ return out;
26
+ }
27
+ return value;
28
+ }
4
29
  export function loadAgentConfig(path) {
5
30
  const raw = readFileSync(path, "utf-8");
6
- const parsed = (yaml.load(raw) ?? {});
31
+ const parsedRaw = (yaml.load(raw) ?? {});
32
+ const parsed = interpolateEnvVars(parsedRaw);
7
33
  const workspace = String(parsed.workspace || parsed.repo || process.cwd());
8
34
  const memoryPath = parsed.memoryPath || `${workspace}/.openclaw/agent.memory.jsonl`;
9
35
  const agent = {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAwB,CAAC;IAE7D,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,SAAS,+BAA+B,CAAC;IAEpF,MAAM,KAAK,GAAgB;QACzB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,IAAI,OAAO,CAAC;QACvD,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC;QACtD,SAAS;QACT,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,SAAS,OAAO,CAAC;QACtD,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;QAC9B,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS;QAC3E,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI;QAC3F,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;QAC7D,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAChE,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,GAAG,EAAE;YACH,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,IAAI,QAAQ;YAC7D,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,aAAa;YACzD,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM;YAC3C,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO;SAC/C;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,OAAO,GAAG,SAAS,qBAAqB,MAAM,QAAQ,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAA2B,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ export declare class AgentRuntime {
9
9
  stop(): Promise<void>;
10
10
  runOnce(message: string): Promise<void>;
11
11
  getState(): string;
12
+ isHealthy(): boolean;
12
13
  describeBoundaries(): string;
13
14
  }
14
15
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,qBAAa,YAAY;aAKK,MAAM,EAAE,WAAW;IAJ/C,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAEf,MAAM,EAAE,WAAW;IAkBzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,QAAQ,IAAI,MAAM;IAIlB,kBAAkB,IAAI,MAAM;CAG7B"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,qBAAa,YAAY;aAKK,MAAM,EAAE,WAAW;IAJ/C,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAEf,MAAM,EAAE,WAAW;IAkBzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,QAAQ,IAAI,MAAM;IAIlB,SAAS,IAAI,OAAO;IAIpB,kBAAkB,IAAI,MAAM;CAG7B"}
@@ -1,3 +1,5 @@
1
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
1
3
  import { EventLoop } from "./event-loop.js";
2
4
  import { MailClient } from "../io/mail.js";
3
5
  import { MemoryStore } from "../io/memory.js";
@@ -28,7 +30,23 @@ export class AgentRuntime {
28
30
  }
29
31
  async start() {
30
32
  const checkInbox = async () => this.mail.checkNewMail();
31
- await this.loop.run(checkInbox);
33
+ const pidPath = join(this.config.workspace, ".tps-agent.pid");
34
+ mkdirSync(dirname(pidPath), { recursive: true });
35
+ writeFileSync(pidPath, `${process.pid}\n`, "utf-8");
36
+ const shutdown = new Promise((resolve) => {
37
+ const onStop = async () => {
38
+ await this.loop.stop();
39
+ resolve();
40
+ };
41
+ process.once("SIGINT", onStop);
42
+ process.once("SIGTERM", onStop);
43
+ });
44
+ try {
45
+ await Promise.race([this.loop.run(checkInbox), shutdown]);
46
+ }
47
+ finally {
48
+ rmSync(pidPath, { force: true });
49
+ }
32
50
  }
33
51
  async stop() {
34
52
  await this.loop.stop();
@@ -39,6 +57,9 @@ export class AgentRuntime {
39
57
  getState() {
40
58
  return this.loop.getState();
41
59
  }
60
+ isHealthy() {
61
+ return this.getState() !== "stopped";
62
+ }
42
63
  describeBoundaries() {
43
64
  return this.boundary.describeCapabilities();
44
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,OAAO,YAAY;IAKK;IAJpB,IAAI,CAAY;IACP,IAAI,CAAa;IACjB,QAAQ,CAAkB;IAE3C,YAA4B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;QAC7C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC,CAAC;QAC/E,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,oBAAoB,CAAC;YACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI;YACJ,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACxD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;IAC9C,CAAC;CACF"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/runtime/agent.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"event-loop.d.ts","sourceRoot":"","sources":["../../src/runtime/event-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EAKX,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,UAAU,aAAa;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAMD,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAiB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHzE,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,OAAO,CAAS;gBAEK,IAAI,EAAE,aAAa,EAAmB,MAAM,SAAM;IAEzE,GAAG,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,QAAQ,IAAI,UAAU;IAIhB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI9B,WAAW;YAIX,cAAc;YAiHd,iBAAiB;YAmBjB,WAAW;CAQ1B"}
1
+ {"version":3,"file":"event-loop.d.ts","sourceRoot":"","sources":["../../src/runtime/event-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAyC,UAAU,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,UAAU,aAAa;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAMD,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAiB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHzE,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,OAAO,CAAS;gBAEK,IAAI,EAAE,aAAa,EAAmB,MAAM,SAAM;IAEzE,GAAG,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,QAAQ,IAAI,UAAU;IAIhB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI9B,WAAW;YAKX,cAAc;YA6Gd,iBAAiB;YAiBjB,WAAW;CAQ1B"}
@@ -48,7 +48,8 @@ export class EventLoop {
48
48
  await this.processMessage(prompt);
49
49
  }
50
50
  async processMail(message) {
51
- await this.processMessage(message.body);
51
+ const body = typeof message.body === "string" ? message.body : JSON.stringify(message.body);
52
+ await this.processMessage(body);
52
53
  }
53
54
  async processMessage(promptRaw) {
54
55
  const prompt = String(promptRaw).trim();
@@ -68,14 +69,13 @@ export class EventLoop {
68
69
  ts: new Date().toISOString(),
69
70
  data: { direction: "in", body: prompt },
70
71
  });
71
- const request = {
72
+ let completion = await this.deps.provider.complete({
72
73
  systemPrompt: await this.buildSystemPrompt(),
73
74
  messages: [{ role: "user", content: prompt }],
74
75
  tools,
75
76
  toolChoice: "auto",
76
77
  maxTokens: this.deps.config.maxTokens ?? 1024,
77
- };
78
- let completion = await this.deps.provider.complete(request);
78
+ });
79
79
  let turns = 0;
80
80
  while (true) {
81
81
  if (completion.content) {
@@ -89,9 +89,8 @@ export class EventLoop {
89
89
  },
90
90
  });
91
91
  }
92
- if (!completion.toolCalls || completion.toolCalls.length === 0) {
92
+ if (!completion.toolCalls || completion.toolCalls.length === 0)
93
93
  return;
94
- }
95
94
  if (turns++ > 8) {
96
95
  await this.deps.memory.append({
97
96
  type: "error",
@@ -107,7 +106,8 @@ export class EventLoop {
107
106
  ts: new Date().toISOString(),
108
107
  data: { tool: call.name, args: call.input },
109
108
  });
110
- if (this.deps.reviewGate && this.deps.reviewGate.isHighRisk(call.name)) {
109
+ const reviewBlocked = this.deps.reviewGate?.isHighRisk(call.name) ?? false;
110
+ if (reviewBlocked) {
111
111
  await this.deps.reviewGate.requestApproval(call.name, call.input);
112
112
  await this.deps.memory.append({
113
113
  type: "approval_request",
@@ -135,14 +135,13 @@ export class EventLoop {
135
135
  content: JSON.stringify(result),
136
136
  });
137
137
  }
138
- const nextMessages = [
139
- ...request.messages,
140
- { role: "assistant", content: completion.content ?? "" },
141
- ...toolMessages,
142
- ];
143
138
  completion = await this.deps.provider.complete({
144
- systemPrompt: request.systemPrompt,
145
- messages: nextMessages,
139
+ systemPrompt: await this.buildSystemPrompt(),
140
+ messages: [
141
+ { role: "user", content: prompt },
142
+ { role: "assistant", content: completion.content ?? "" },
143
+ ...toolMessages,
144
+ ],
146
145
  tools,
147
146
  toolChoice: "auto",
148
147
  maxTokens: this.deps.config.maxTokens ?? 1024,
@@ -150,20 +149,19 @@ export class EventLoop {
150
149
  }
151
150
  }
152
151
  async buildSystemPrompt() {
153
- const fs = await import("node:fs/promises");
154
152
  const docs = await Promise.all([
155
153
  this.fileOrEmpty(`${this.deps.config.workspace}/SOUL.md`),
156
154
  this.fileOrEmpty(`${this.deps.config.workspace}/AGENTS.md`),
157
155
  this.fileOrEmpty(`${this.deps.config.workspace}/IDENTITY.md`),
158
156
  Promise.resolve(this.deps.config.systemPrompt || ""),
159
157
  ]);
160
- const sections = [
158
+ const docBlock = docs.filter(Boolean).join("\n\n");
159
+ return [
160
+ docBlock,
161
161
  `Role: ${this.deps.config.name}`,
162
162
  `Tools: ${this.deps.tools.list().map((t) => t.name).join(", ") || "(none)"}`,
163
163
  `Context: ${this.deps.config.agentId}`,
164
- ];
165
- const docBlock = docs.filter(Boolean).join("\n\n");
166
- return `${docBlock}\n\n${sections.join("\n")}`;
164
+ ].join("\n");
167
165
  }
168
166
  async fileOrEmpty(path) {
169
167
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"event-loop.js","sourceRoot":"","sources":["../../src/runtime/event-loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-loop.js","sourceRoot":"","sources":["../../src/runtime/event-loop.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tpsdev-ai/agent",
3
- "version": "0.4.2",
4
- "description": "Native TPS Agent Runtime \u2014 headless, mail-driven, nono-sandboxed",
3
+ "version": "0.5.0",
4
+ "description": "Native TPS Agent Runtime headless, mail-driven, nono-sandboxed",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
package/src/bin.ts CHANGED
@@ -3,38 +3,58 @@ import { AgentRuntime } from "./runtime/agent.js";
3
3
  import { loadAgentConfig } from "./config.js";
4
4
 
5
5
  function usage(): never {
6
- console.error("Usage: tps-agent run --config <agent.yaml> --message <text>");
6
+ console.error("Usage:");
7
+ console.error(" tps-agent run --config <agent.yaml> --message <text>");
8
+ console.error(" tps-agent start --config <agent.yaml>");
9
+ console.error(" tps-agent health --config <agent.yaml>");
7
10
  process.exit(1);
8
11
  }
9
12
 
10
- async function main() {
11
- const args = process.argv.slice(2);
12
- const cmd = args[0];
13
-
14
- if (cmd !== "run") {
15
- usage();
16
- }
17
-
18
- const configIdx = args.indexOf("--config");
19
- const msgIdx = args.indexOf("--message");
20
-
21
- if (configIdx < 0 || msgIdx < 0) {
22
- usage();
23
- }
13
+ function parseArg(name: string, args: string[]): string | undefined {
14
+ const idx = args.indexOf(name);
15
+ if (idx >= 0 && idx + 1 < args.length) return args[idx + 1];
16
+ return undefined;
17
+ }
24
18
 
25
- const configPath = args[configIdx + 1];
26
- const message = args.slice(msgIdx + 1).join(" ");
19
+ function parseConfig(args: string[]): { configPath?: string; command?: string } {
20
+ const command = args[0];
21
+ const configPath = parseArg("--config", args);
22
+ return { command, configPath };
23
+ }
27
24
 
28
- if (!configPath || !message) {
29
- usage();
30
- }
25
+ async function main() {
26
+ const args = process.argv.slice(2);
27
+ const { command, configPath } = parseConfig(args);
28
+ if (!command || command === "--help" || command === "-h") usage();
29
+ if (!configPath) usage();
31
30
 
32
31
  const config = loadAgentConfig(configPath);
33
32
  const runtime = new AgentRuntime(config);
34
- await runtime.runOnce(message);
33
+
34
+ switch (command) {
35
+ case "run": {
36
+ const messageIdx = args.indexOf("--message");
37
+ const message = messageIdx >= 0 ? args.slice(messageIdx + 1).join(" ") : process.env.TPS_AGENT_MESSAGE;
38
+ if (!message) usage();
39
+ await runtime.runOnce(message);
40
+ return;
41
+ }
42
+ case "start": {
43
+ await runtime.start();
44
+ return;
45
+ }
46
+ case "health": {
47
+ const healthy = runtime.isHealthy();
48
+ process.stdout.write(healthy ? "healthy\n" : "unhealthy\n");
49
+ process.exit(healthy ? 0 : 1);
50
+ return;
51
+ }
52
+ default:
53
+ usage();
54
+ }
35
55
  }
36
56
 
37
57
  main().catch((err) => {
38
- console.error(err?.message || err);
58
+ console.error(String(err?.message || err));
39
59
  process.exit(1);
40
60
  });
package/src/config.ts CHANGED
@@ -22,9 +22,40 @@ export interface AgentRuntimeConfig {
22
22
  execAllowlist?: string[];
23
23
  }
24
24
 
25
+ function interpolateEnvInString(raw: string): string {
26
+ return raw.replace(/\$\{([A-Z0-9_]+)\}/g, (_match, varName: string) => {
27
+ const resolved = process.env[varName];
28
+ if (resolved === undefined) {
29
+ throw new Error(`Missing environment variable: ${varName}`);
30
+ }
31
+ return resolved;
32
+ });
33
+ }
34
+
35
+ function interpolateEnvVars<T>(value: T): T {
36
+ if (typeof value === "string") {
37
+ return interpolateEnvInString(value) as T;
38
+ }
39
+
40
+ if (Array.isArray(value)) {
41
+ return value.map((item) => interpolateEnvVars(item)) as T;
42
+ }
43
+
44
+ if (value && typeof value === "object") {
45
+ const out: Record<string, unknown> = {};
46
+ for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
47
+ out[k] = interpolateEnvVars(v);
48
+ }
49
+ return out as T;
50
+ }
51
+
52
+ return value;
53
+ }
54
+
25
55
  export function loadAgentConfig(path: string): AgentConfig {
26
56
  const raw = readFileSync(path, "utf-8");
27
- const parsed = (yaml.load(raw) ?? {}) as Record<string, any>;
57
+ const parsedRaw = (yaml.load(raw) ?? {}) as Record<string, any>;
58
+ const parsed = interpolateEnvVars(parsedRaw);
28
59
 
29
60
  const workspace = String(parsed.workspace || parsed.repo || process.cwd());
30
61
  const memoryPath = parsed.memoryPath || `${workspace}/.openclaw/agent.memory.jsonl`;
@@ -1,3 +1,5 @@
1
+ import { mkdirSync, writeFileSync, rmSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
1
3
  import type { AgentConfig } from "./types.js";
2
4
  import { EventLoop } from "./event-loop.js";
3
5
  import { MailClient } from "../io/mail.js";
@@ -32,7 +34,24 @@ export class AgentRuntime {
32
34
 
33
35
  async start(): Promise<void> {
34
36
  const checkInbox = async () => this.mail.checkNewMail();
35
- await this.loop.run(checkInbox);
37
+ const pidPath = join(this.config.workspace, ".tps-agent.pid");
38
+ mkdirSync(dirname(pidPath), { recursive: true });
39
+ writeFileSync(pidPath, `${process.pid}\n`, "utf-8");
40
+
41
+ const shutdown = new Promise<void>((resolve) => {
42
+ const onStop = async () => {
43
+ await this.loop.stop();
44
+ resolve();
45
+ };
46
+ process.once("SIGINT", onStop);
47
+ process.once("SIGTERM", onStop);
48
+ });
49
+
50
+ try {
51
+ await Promise.race([this.loop.run(checkInbox), shutdown]);
52
+ } finally {
53
+ rmSync(pidPath, { force: true });
54
+ }
36
55
  }
37
56
 
38
57
  async stop(): Promise<void> {
@@ -47,6 +66,10 @@ export class AgentRuntime {
47
66
  return this.loop.getState();
48
67
  }
49
68
 
69
+ isHealthy(): boolean {
70
+ return this.getState() !== "stopped";
71
+ }
72
+
50
73
  describeBoundaries(): string {
51
74
  return this.boundary.describeCapabilities();
52
75
  }
@@ -1,12 +1,5 @@
1
1
  import type { MailMessage } from "../io/mail.js";
2
- import type {
3
- AgentConfig,
4
- AgentState,
5
- CompletionRequest,
6
- CompletionResponse,
7
- ToolCall,
8
- ToolSpec,
9
- } from "./types.js";
2
+ import type { AgentConfig, CompletionRequest, ToolCall, ToolSpec, AgentState } from "./types.js";
10
3
  import type { MemoryStore } from "../io/memory.js";
11
4
  import type { ContextManager } from "../io/context.js";
12
5
  import type { ProviderManager } from "../llm/provider.js";
@@ -72,7 +65,8 @@ export class EventLoop {
72
65
  }
73
66
 
74
67
  private async processMail(message: MailMessage): Promise<void> {
75
- await this.processMessage(message.body);
68
+ const body = typeof message.body === "string" ? message.body : JSON.stringify(message.body);
69
+ await this.processMessage(body);
76
70
  }
77
71
 
78
72
  private async processMessage(promptRaw: string): Promise<void> {
@@ -96,15 +90,14 @@ export class EventLoop {
96
90
  data: { direction: "in", body: prompt },
97
91
  });
98
92
 
99
- const request: CompletionRequest = {
93
+ let completion = await this.deps.provider.complete({
100
94
  systemPrompt: await this.buildSystemPrompt(),
101
95
  messages: [{ role: "user", content: prompt }],
102
96
  tools,
103
97
  toolChoice: "auto",
104
98
  maxTokens: this.deps.config.maxTokens ?? 1024,
105
- };
99
+ });
106
100
 
107
- let completion = await this.deps.provider.complete(request);
108
101
  let turns = 0;
109
102
 
110
103
  while (true) {
@@ -120,9 +113,7 @@ export class EventLoop {
120
113
  });
121
114
  }
122
115
 
123
- if (!completion.toolCalls || completion.toolCalls.length === 0) {
124
- return;
125
- }
116
+ if (!completion.toolCalls || completion.toolCalls.length === 0) return;
126
117
 
127
118
  if (turns++ > 8) {
128
119
  await this.deps.memory.append({
@@ -141,8 +132,9 @@ export class EventLoop {
141
132
  data: { tool: call.name, args: call.input },
142
133
  });
143
134
 
144
- if (this.deps.reviewGate && this.deps.reviewGate.isHighRisk(call.name)) {
145
- await this.deps.reviewGate.requestApproval(call.name, call.input);
135
+ const reviewBlocked = this.deps.reviewGate?.isHighRisk(call.name) ?? false;
136
+ if (reviewBlocked) {
137
+ await this.deps.reviewGate!.requestApproval(call.name, call.input);
146
138
  await this.deps.memory.append({
147
139
  type: "approval_request",
148
140
  ts: new Date().toISOString(),
@@ -172,15 +164,13 @@ export class EventLoop {
172
164
  });
173
165
  }
174
166
 
175
- const nextMessages = [
176
- ...request.messages,
177
- { role: "assistant", content: completion.content ?? "" },
178
- ...toolMessages,
179
- ];
180
-
181
167
  completion = await this.deps.provider.complete({
182
- systemPrompt: request.systemPrompt,
183
- messages: nextMessages,
168
+ systemPrompt: await this.buildSystemPrompt(),
169
+ messages: [
170
+ { role: "user", content: prompt },
171
+ { role: "assistant", content: completion.content ?? "" },
172
+ ...toolMessages,
173
+ ] as any,
184
174
  tools,
185
175
  toolChoice: "auto",
186
176
  maxTokens: this.deps.config.maxTokens ?? 1024,
@@ -189,7 +179,6 @@ export class EventLoop {
189
179
  }
190
180
 
191
181
  private async buildSystemPrompt(): Promise<string> {
192
- const fs = await import("node:fs/promises");
193
182
  const docs = await Promise.all([
194
183
  this.fileOrEmpty(`${this.deps.config.workspace}/SOUL.md`),
195
184
  this.fileOrEmpty(`${this.deps.config.workspace}/AGENTS.md`),
@@ -197,14 +186,13 @@ export class EventLoop {
197
186
  Promise.resolve(this.deps.config.systemPrompt || ""),
198
187
  ]);
199
188
 
200
- const sections = [
189
+ const docBlock = docs.filter(Boolean).join("\n\n");
190
+ return [
191
+ docBlock,
201
192
  `Role: ${this.deps.config.name}`,
202
193
  `Tools: ${this.deps.tools.list().map((t) => t.name).join(", ") || "(none)"}`,
203
194
  `Context: ${this.deps.config.agentId}`,
204
- ];
205
-
206
- const docBlock = docs.filter(Boolean).join("\n\n");
207
- return `${docBlock}\n\n${sections.join("\n")}`;
195
+ ].join("\n");
208
196
  }
209
197
 
210
198
  private async fileOrEmpty(path: string): Promise<string> {
@@ -0,0 +1,67 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { loadAgentConfig } from "../src/config.js";
6
+
7
+ describe("agent config env interpolation", () => {
8
+ let dir: string;
9
+
10
+ beforeEach(() => {
11
+ dir = mkdtempSync(join(tmpdir(), "tps-agent-config-"));
12
+ });
13
+
14
+ afterEach(() => {
15
+ rmSync(dir, { recursive: true, force: true });
16
+ delete process.env.ANTHROPIC_API_KEY;
17
+ delete process.env.AGENT_WORKSPACE;
18
+ delete process.env.AGENT_NAME;
19
+ });
20
+
21
+ test("resolves ${VAR_NAME} placeholders in string values", () => {
22
+ process.env.ANTHROPIC_API_KEY = "test-key";
23
+ process.env.AGENT_WORKSPACE = "/tmp/ws";
24
+ process.env.AGENT_NAME = "Coder";
25
+
26
+ const cfg = join(dir, "agent.yaml");
27
+ writeFileSync(
28
+ cfg,
29
+ [
30
+ "agentId: coder",
31
+ "name: ${AGENT_NAME}",
32
+ "workspace: ${AGENT_WORKSPACE}",
33
+ "mailDir: ${AGENT_WORKSPACE}/mail",
34
+ "llm:",
35
+ " provider: anthropic",
36
+ " model: claude-sonnet-4-6",
37
+ " apiKey: ${ANTHROPIC_API_KEY}",
38
+ ].join("\n"),
39
+ "utf-8"
40
+ );
41
+
42
+ const parsed = loadAgentConfig(cfg);
43
+ expect(parsed.name).toBe("Coder");
44
+ expect(parsed.workspace).toBe("/tmp/ws");
45
+ expect(parsed.mailDir).toBe("/tmp/ws/mail");
46
+ expect(parsed.llm.apiKey).toBe("test-key");
47
+ });
48
+
49
+ test("throws when referenced env var is missing", () => {
50
+ const cfg = join(dir, "agent-missing.yaml");
51
+ writeFileSync(
52
+ cfg,
53
+ [
54
+ "agentId: coder",
55
+ "name: Coder",
56
+ "workspace: /tmp/ws",
57
+ "llm:",
58
+ " provider: anthropic",
59
+ " model: claude-sonnet-4-6",
60
+ " apiKey: ${MISSING_API_KEY}",
61
+ ].join("\n"),
62
+ "utf-8"
63
+ );
64
+
65
+ expect(() => loadAgentConfig(cfg)).toThrow("Missing environment variable: MISSING_API_KEY");
66
+ });
67
+ });