@securecoms/agent-runtime 0.1.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/PROVENANCE.md ADDED
@@ -0,0 +1,28 @@
1
+ # Provenance
2
+
3
+ This package is a first-party agent runtime for SecureComs. Some brain logic
4
+ (LLM dispatch loop, memory, skill invocation, tool running, config shape) is
5
+ ported from `agentvault-federal`'s `packages/agent-runtime/src/`, which is
6
+ read-only reference material — never a dependency. The `@agentvault/*` cord
7
+ is cut: no runtime import of any `@agentvault/*` package, `apiUrl`, or
8
+ `deviceJwt` concept survives the port (enforced by
9
+ `src/no-agentvault-deps.test.ts`).
10
+
11
+ Source repo HEAD at the time of cloning: `dda9700cf2e68dfd7f3d341c6794e097c298c6c4`
12
+ (`git -C ~/projects/agentvault-federal rev-parse HEAD`).
13
+
14
+ | file | source (agentvault-federal path) | source SHA | last reviewed |
15
+ | --- | --- | --- | --- |
16
+ | `src/llm-dispatch.ts` | `packages/agent-runtime/src/llm-dispatch.ts` | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 |
17
+ | `src/memory.ts` | `packages/agent-runtime/src/memory.ts` | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 |
18
+ | `src/skill-invoker.ts` | `packages/agent-runtime/src/skill-invoker.ts` | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 |
19
+ | `src/tool-runner.ts` | `packages/agent-runtime/src/tool-runner.ts` | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 |
20
+ | `src/config.ts` | `packages/agent-runtime/src/config.ts` | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 — shape only — federal fields removed |
21
+ | `src/turn-loop.ts` | `packages/agent-runtime/src/index.ts` (handler, lines ~132–214) | dda9700cf2e68dfd7f3d341c6794e097c298c6c4 | 2026-09-08 — handler loop ported; gate step added |
22
+
23
+ Note: `tool-gate-hook.ts` in the source repo is **re-implemented**, not
24
+ cloned — a later task rebuilds the tool-gate behavior against this package's
25
+ own transport, so no row is seeded for it here.
26
+
27
+ This table is complete as of 2026-09-08 and should be re-reviewed if the
28
+ source repo's files move or are re-cut.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @securecoms/agent-runtime
2
+
3
+ A first-party SecureComs agent. It attaches to the local SecureComs daemon
4
+ and runs a BYO (bring-your-own) OpenAI-compatible LLM against incoming
5
+ messages, with skills, per-channel memory, and a local tool gate — no
6
+ AgentVault backend involved.
7
+
8
+ ## Install and run
9
+
10
+ ```
11
+ npm i -g @securecoms/agent-runtime
12
+ securecoms-agent --identity <identity_id>
13
+ ```
14
+
15
+ `<identity_id>` (or `SECURECOMS_IDENTITY`) selects which local daemon
16
+ connection this process serves.
17
+
18
+ ## Running it at login (service install)
19
+
20
+ ```
21
+ securecoms-agent install --identity <identity_id> [--llm-endpoint <url>] \
22
+ [--llm-model <model>] [--llm-key-file <path>] [--skills-dir <dir>] \
23
+ [--data-dir <dir>] [--exec-path <node>]
24
+ securecoms-agent install --identity <identity_id> --dry-run
25
+ securecoms-agent uninstall --identity <identity_id>
26
+ ```
27
+
28
+ Every install flag also reads its `SECURECOMS_*` variable from the environment
29
+ when the flag is absent (`SECURECOMS_IDENTITY`, `SECURECOMS_LLM_ENDPOINT`,
30
+ `SECURECOMS_LLM_MODEL`, `SECURECOMS_LLM_API_KEY_FILE`, `SECURECOMS_SKILLS_DIR`,
31
+ `SECURECOMS_DATA_DIR`), so an operator who already exports the run-mode
32
+ environment can just run `securecoms-agent install`. The flag always wins.
33
+ `--exec-path` is the one exception: it is never taken from the environment.
34
+ `--dry-run` prints the resolved Node path, the service file path, the log
35
+ path, the key file, and the rendered plist/unit **without writing anything or
36
+ calling `launchctl`/`systemctl`** — use it to inspect an install before making
37
+ it.
38
+
39
+ `install` writes a per-user service that starts the agent at login and
40
+ restarts it on crash — a launchd LaunchAgent at
41
+ `~/Library/LaunchAgents/com.securecoms.agent.<slug>.plist` on macOS (logs at
42
+ `~/Library/Logs/securecoms-agent-<slug>.log`), a systemd `--user` unit at
43
+ `~/.config/systemd/user/securecoms-agent-<slug>.service` on Linux
44
+ (`journalctl --user -u securecoms-agent-<slug> -f`). `<slug>` is the first
45
+ eight characters of the identity when they are lowercase hex (the usual case:
46
+ identities are UUIDs), otherwise the whole identity slugified to
47
+ `[a-z0-9-]`. Any other platform is refused.
48
+
49
+ Only the non-secret settings you pass are baked into the service definition,
50
+ under their `SECURECOMS_*` names; anything you omit falls back to the
51
+ runtime's own default. **The installer never accepts or writes an API key
52
+ value — only `--llm-key-file <path>`**, so no secret reaches the plist, the
53
+ unit file, or a process listing. If `--llm-key-file` is given, install checks the file is
54
+ readable and refuses otherwise — a key file the agent cannot read would make
55
+ it exit 2 on every start, and the service manager would restart-loop that
56
+ failure.
57
+
58
+ The Node interpreter baked into the service must survive a reboot and an
59
+ upgrade, so install does not simply use the Node you ran it with: a path whose
60
+ location encodes a version (a Homebrew Cellar keg, or nvm/asdf/fnm/volta/n) is
61
+ resolved to a stable equivalent — `/usr/local/bin/node`,
62
+ `/opt/homebrew/bin/node`, `/opt/homebrew/opt/node/bin/node`, `/usr/bin/node`,
63
+ or `~/.local/bin/node`, preferring one that is the same real file as the Node
64
+ you ran, and requiring Node >= 22 on the running architecture. If no stable
65
+ Node exists, install refuses and tells you to install one or pass
66
+ `--exec-path <path>`, which overrides the choice outright.
67
+
68
+ ## Connection and identity
69
+
70
+ The runtime never reads a token from the environment. It reads the
71
+ connection file at `~/.securecoms/connections/<identity_id>.json`, which
72
+ names a token file on disk; the token itself is read from that file, not
73
+ passed on the command line or in an env var. Before any socket opens, the
74
+ runtime checks a two-anchor identity gate: the identity baked into this
75
+ process (from `--identity`/`SECURECOMS_IDENTITY`) must match both the
76
+ identity recorded in the connection file and the identity the local daemon
77
+ reports on its health endpoint. Any mismatch refuses the connection outright.
78
+
79
+ ## Configuration
80
+
81
+ All configuration is via `SECURECOMS_*` environment variables (see
82
+ `src/config.ts` for the source of truth):
83
+
84
+ | Variable | Default | Purpose |
85
+ | --- | --- | --- |
86
+ | `SECURECOMS_IDENTITY` | — (or `--identity <id>`) | Which local daemon connection to serve |
87
+ | `SECURECOMS_LLM_ENDPOINT` | `http://127.0.0.1:11434` | Base URL of an OpenAI-compatible LLM server, with or without a trailing `/v1` |
88
+ | `SECURECOMS_LLM_MODEL` | `llama3` | Model name to request |
89
+ | `SECURECOMS_LLM_API_KEY` | unset | API key for the LLM endpoint, if it requires one |
90
+ | `SECURECOMS_LLM_API_KEY_FILE` | unset (or `--llm-key-file <path>`) | File holding the API key (trimmed on read). Preferred: it wins over `SECURECOMS_LLM_API_KEY`, and it is the only key form the service installer accepts. An unreadable or empty file exits 2 |
91
+ | `SECURECOMS_SKILLS_DIR` | this package's own `skills/` | Directory of skill manifests to load |
92
+ | `SECURECOMS_DATA_DIR` | `~/.securecoms/agent-runtime` | Root directory for per-channel state |
93
+ | `SECURECOMS_LOG_LEVEL` | `info` | One of `debug`, `info`, `warn`, `error` |
94
+ | `SECURECOMS_TOOL_ALLOW` | `echo` | Comma-separated tool allow-list |
95
+ | `SECURECOMS_TOOL_DENY` | unset | Comma-separated tool deny-list (wins over allow) |
96
+ | `SECURECOMS_TOOL_DEFAULT` | `deny` | Fallback policy for a tool matched by neither list |
97
+
98
+ ## Memory
99
+
100
+ Memory is local only, never sent anywhere but the configured LLM endpoint,
101
+ and scoped per channel under `<dataDir>/channels/<channel>/` — one channel's
102
+ history and captured memories never leak into another channel's turn.
103
+
104
+ ## Adding a skill
105
+
106
+ Drop a manifest under `SECURECOMS_SKILLS_DIR`, either as a flat
107
+ `<skillsDir>/<name>.json` file or as `<skillsDir>/<dir>/manifest.json`. A
108
+ manifest needs `name`, `description`, a JSON-Schema `parameters` object, and
109
+ a `handler`:
110
+
111
+ - `builtin:<name>` — one of the runtime's built-in handlers (currently
112
+ `echo`, `timestamp`).
113
+ - `script:<path>` — an executable file, path relative to `skillsDir` and
114
+ contained within it (symlinks included — a link that resolves outside
115
+ `skillsDir` is refused). It runs with its arguments as JSON on stdin, cwd
116
+ set to `skillsDir`, and a minimal environment (no inherited secrets).
117
+
118
+ A manifest with any other handler shape is skipped with a warning, and a
119
+ skill invocation that throws is turned into a `tool_failed` tool message
120
+ rather than dropping the turn.
121
+
122
+ ## Provenance
123
+
124
+ See [PROVENANCE.md](./PROVENANCE.md) for which files were ported from
125
+ `agentvault-federal`'s reference `agent-runtime` package and how the
126
+ AgentVault package-dependency cord was cut.