natroc 0.0.1

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 (183) hide show
  1. package/AGENTS.md +494 -0
  2. package/LICENSE +7 -0
  3. package/README.md +0 -0
  4. package/install.ps1 +109 -0
  5. package/install.sh +132 -0
  6. package/package.json +77 -0
  7. package/server/dist/agent/agent-loop.d.ts +71 -0
  8. package/server/dist/agent/agent-loop.js +171 -0
  9. package/server/dist/agent/agent-loop.js.map +1 -0
  10. package/server/dist/agent/home-context.d.ts +29 -0
  11. package/server/dist/agent/home-context.js +134 -0
  12. package/server/dist/agent/home-context.js.map +1 -0
  13. package/server/dist/agent/improvement-engine.d.ts +23 -0
  14. package/server/dist/agent/improvement-engine.js +107 -0
  15. package/server/dist/agent/improvement-engine.js.map +1 -0
  16. package/server/dist/agent/tools/index.d.ts +14 -0
  17. package/server/dist/agent/tools/index.js +85 -0
  18. package/server/dist/agent/tools/index.js.map +1 -0
  19. package/server/dist/agent/tools/list-directory.d.ts +2 -0
  20. package/server/dist/agent/tools/list-directory.js +27 -0
  21. package/server/dist/agent/tools/list-directory.js.map +1 -0
  22. package/server/dist/agent/tools/read-file.d.ts +2 -0
  23. package/server/dist/agent/tools/read-file.js +30 -0
  24. package/server/dist/agent/tools/read-file.js.map +1 -0
  25. package/server/dist/agent/tools/run-command.d.ts +2 -0
  26. package/server/dist/agent/tools/run-command.js +72 -0
  27. package/server/dist/agent/tools/run-command.js.map +1 -0
  28. package/server/dist/agent/tools/system-info.d.ts +2 -0
  29. package/server/dist/agent/tools/system-info.js +28 -0
  30. package/server/dist/agent/tools/system-info.js.map +1 -0
  31. package/server/dist/agent/tools/types.d.ts +18 -0
  32. package/server/dist/agent/tools/types.js +2 -0
  33. package/server/dist/agent/tools/types.js.map +1 -0
  34. package/server/dist/agent/tools/util.d.ts +7 -0
  35. package/server/dist/agent/tools/util.js +24 -0
  36. package/server/dist/agent/tools/util.js.map +1 -0
  37. package/server/dist/agent/tools/write-file.d.ts +2 -0
  38. package/server/dist/agent/tools/write-file.js +25 -0
  39. package/server/dist/agent/tools/write-file.js.map +1 -0
  40. package/server/dist/app.d.ts +8 -0
  41. package/server/dist/app.js +39 -0
  42. package/server/dist/app.js.map +1 -0
  43. package/server/dist/auth/password.d.ts +7 -0
  44. package/server/dist/auth/password.js +20 -0
  45. package/server/dist/auth/password.js.map +1 -0
  46. package/server/dist/channels/channel-runtime.d.ts +32 -0
  47. package/server/dist/channels/channel-runtime.js +484 -0
  48. package/server/dist/channels/channel-runtime.js.map +1 -0
  49. package/server/dist/cli/agent-deliver.d.ts +14 -0
  50. package/server/dist/cli/agent-deliver.js +183 -0
  51. package/server/dist/cli/agent-deliver.js.map +1 -0
  52. package/server/dist/cli/args.d.ts +11 -0
  53. package/server/dist/cli/args.js +57 -0
  54. package/server/dist/cli/args.js.map +1 -0
  55. package/server/dist/cli/cli-token.d.ts +1 -0
  56. package/server/dist/cli/cli-token.js +22 -0
  57. package/server/dist/cli/cli-token.js.map +1 -0
  58. package/server/dist/cli/daemon.d.ts +2 -0
  59. package/server/dist/cli/daemon.js +252 -0
  60. package/server/dist/cli/daemon.js.map +1 -0
  61. package/server/dist/cli.d.ts +2 -0
  62. package/server/dist/cli.js +416 -0
  63. package/server/dist/cli.js.map +1 -0
  64. package/server/dist/config/natroc-home.d.ts +13 -0
  65. package/server/dist/config/natroc-home.js +730 -0
  66. package/server/dist/config/natroc-home.js.map +1 -0
  67. package/server/dist/gateway/agent-service.d.ts +16 -0
  68. package/server/dist/gateway/agent-service.js +261 -0
  69. package/server/dist/gateway/agent-service.js.map +1 -0
  70. package/server/dist/gateway/connection.d.ts +38 -0
  71. package/server/dist/gateway/connection.js +254 -0
  72. package/server/dist/gateway/connection.js.map +1 -0
  73. package/server/dist/gateway/gateway.d.ts +79 -0
  74. package/server/dist/gateway/gateway.js +150 -0
  75. package/server/dist/gateway/gateway.js.map +1 -0
  76. package/server/dist/gateway/index.d.ts +8 -0
  77. package/server/dist/gateway/index.js +26 -0
  78. package/server/dist/gateway/index.js.map +1 -0
  79. package/server/dist/gateway/protocol.d.ts +102 -0
  80. package/server/dist/gateway/protocol.js +63 -0
  81. package/server/dist/gateway/protocol.js.map +1 -0
  82. package/server/dist/gateway/rpc/agent.d.ts +3 -0
  83. package/server/dist/gateway/rpc/agent.js +174 -0
  84. package/server/dist/gateway/rpc/agent.js.map +1 -0
  85. package/server/dist/gateway/rpc/agents.d.ts +2 -0
  86. package/server/dist/gateway/rpc/agents.js +68 -0
  87. package/server/dist/gateway/rpc/agents.js.map +1 -0
  88. package/server/dist/gateway/rpc/auth.d.ts +3 -0
  89. package/server/dist/gateway/rpc/auth.js +180 -0
  90. package/server/dist/gateway/rpc/auth.js.map +1 -0
  91. package/server/dist/gateway/rpc/channels.d.ts +2 -0
  92. package/server/dist/gateway/rpc/channels.js +230 -0
  93. package/server/dist/gateway/rpc/channels.js.map +1 -0
  94. package/server/dist/gateway/rpc/conversations.d.ts +3 -0
  95. package/server/dist/gateway/rpc/conversations.js +36 -0
  96. package/server/dist/gateway/rpc/conversations.js.map +1 -0
  97. package/server/dist/gateway/rpc/projects.d.ts +3 -0
  98. package/server/dist/gateway/rpc/projects.js +49 -0
  99. package/server/dist/gateway/rpc/projects.js.map +1 -0
  100. package/server/dist/gateway/rpc/providers.d.ts +3 -0
  101. package/server/dist/gateway/rpc/providers.js +106 -0
  102. package/server/dist/gateway/rpc/providers.js.map +1 -0
  103. package/server/dist/gateway/rpc/usage.d.ts +2 -0
  104. package/server/dist/gateway/rpc/usage.js +41 -0
  105. package/server/dist/gateway/rpc/usage.js.map +1 -0
  106. package/server/dist/gateway/types.d.ts +43 -0
  107. package/server/dist/gateway/types.js +20 -0
  108. package/server/dist/gateway/types.js.map +1 -0
  109. package/server/dist/gateway/ws-server.d.ts +10 -0
  110. package/server/dist/gateway/ws-server.js +37 -0
  111. package/server/dist/gateway/ws-server.js.map +1 -0
  112. package/server/dist/index.d.ts +1 -0
  113. package/server/dist/index.js +9 -0
  114. package/server/dist/index.js.map +1 -0
  115. package/server/dist/local-runtime.d.ts +9 -0
  116. package/server/dist/local-runtime.js +16 -0
  117. package/server/dist/local-runtime.js.map +1 -0
  118. package/server/dist/providers/configured-adapters.d.ts +9 -0
  119. package/server/dist/providers/configured-adapters.js +34 -0
  120. package/server/dist/providers/configured-adapters.js.map +1 -0
  121. package/server/dist/providers/ollama.d.ts +23 -0
  122. package/server/dist/providers/ollama.js +164 -0
  123. package/server/dist/providers/ollama.js.map +1 -0
  124. package/server/dist/providers/openrouter.d.ts +24 -0
  125. package/server/dist/providers/openrouter.js +201 -0
  126. package/server/dist/providers/openrouter.js.map +1 -0
  127. package/server/dist/providers/thinking.d.ts +18 -0
  128. package/server/dist/providers/thinking.js +58 -0
  129. package/server/dist/providers/thinking.js.map +1 -0
  130. package/server/dist/providers/types.d.ts +55 -0
  131. package/server/dist/providers/types.js +2 -0
  132. package/server/dist/providers/types.js.map +1 -0
  133. package/server/dist/routes/schemas.d.ts +51 -0
  134. package/server/dist/routes/schemas.js +53 -0
  135. package/server/dist/routes/schemas.js.map +1 -0
  136. package/server/dist/runtime.d.ts +47 -0
  137. package/server/dist/runtime.js +29 -0
  138. package/server/dist/runtime.js.map +1 -0
  139. package/server/dist/server.d.ts +11 -0
  140. package/server/dist/server.js +19 -0
  141. package/server/dist/server.js.map +1 -0
  142. package/server/dist/storage/agent-repository.d.ts +59 -0
  143. package/server/dist/storage/agent-repository.js +192 -0
  144. package/server/dist/storage/agent-repository.js.map +1 -0
  145. package/server/dist/storage/auth-repository.d.ts +49 -0
  146. package/server/dist/storage/auth-repository.js +139 -0
  147. package/server/dist/storage/auth-repository.js.map +1 -0
  148. package/server/dist/storage/channel-repository.d.ts +152 -0
  149. package/server/dist/storage/channel-repository.js +413 -0
  150. package/server/dist/storage/channel-repository.js.map +1 -0
  151. package/server/dist/storage/conversation-repository.d.ts +63 -0
  152. package/server/dist/storage/conversation-repository.js +196 -0
  153. package/server/dist/storage/conversation-repository.js.map +1 -0
  154. package/server/dist/storage/database.d.ts +11 -0
  155. package/server/dist/storage/database.js +360 -0
  156. package/server/dist/storage/database.js.map +1 -0
  157. package/server/dist/storage/memory-repository.d.ts +70 -0
  158. package/server/dist/storage/memory-repository.js +279 -0
  159. package/server/dist/storage/memory-repository.js.map +1 -0
  160. package/server/dist/storage/project-repository.d.ts +25 -0
  161. package/server/dist/storage/project-repository.js +67 -0
  162. package/server/dist/storage/project-repository.js.map +1 -0
  163. package/server/dist/storage/provider-repository.d.ts +44 -0
  164. package/server/dist/storage/provider-repository.js +159 -0
  165. package/server/dist/storage/provider-repository.js.map +1 -0
  166. package/server/dist/storage/tool-call-repository.d.ts +35 -0
  167. package/server/dist/storage/tool-call-repository.js +83 -0
  168. package/server/dist/storage/tool-call-repository.js.map +1 -0
  169. package/server/dist/storage/usage-repository.d.ts +76 -0
  170. package/server/dist/storage/usage-repository.js +249 -0
  171. package/server/dist/storage/usage-repository.js.map +1 -0
  172. package/server/dist/storage/vault.d.ts +3 -0
  173. package/server/dist/storage/vault.js +57 -0
  174. package/server/dist/storage/vault.js.map +1 -0
  175. package/ui/README.md +0 -0
  176. package/ui/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  177. package/ui/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  178. package/ui/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  179. package/ui/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  180. package/ui/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  181. package/ui/dist/assets/index-DKaFmZNO.js +114 -0
  182. package/ui/dist/assets/index-DOfPcjx3.css +2 -0
  183. package/ui/dist/index.html +14 -0
package/install.sh ADDED
@@ -0,0 +1,132 @@
1
+ #!/bin/sh
2
+ # Natroc installer — Unix / macOS / Linux / WSL
3
+ #
4
+ # Default:
5
+ # curl -fsSL https://natroc.ai/install.sh | sh
6
+ #
7
+ # Variants (set env BEFORE pipe):
8
+ # NATROC_INSTALL_METHOD=git curl -fsSL .../install.sh | sh # clone + build from source
9
+ # NATROC_INSTALL_METHOD=tarball NATROC_TARBALL_URL=URL ... # install .tgz
10
+ # NATROC_INSTALL_DIR=$HOME/apps/natroc ... # custom source dir (git mode)
11
+ set -eu
12
+
13
+ REQUIRED_NODE_MAJOR=24
14
+ PACKAGE_NAME="natroc"
15
+ GIT_REPO="https://github.com/Licentora/Natroc.git"
16
+ INSTALL_DIR="${NATROC_INSTALL_DIR:-${HOME}/.natroc}"
17
+ SRC_DIR="${INSTALL_DIR}/src"
18
+ METHOD="${NATROC_INSTALL_METHOD:-npm}"
19
+
20
+ # ----- helpers ---------------------------------------------------------------
21
+
22
+ err() { printf 'Error: %s\n' "$1" >&2; }
23
+ info() { printf '%s\n' "$1"; }
24
+
25
+ require_cmd() {
26
+ if ! command -v "$1" >/dev/null 2>&1; then
27
+ err "$1 is required but not found in PATH."
28
+ [ -n "${2:-}" ] && err "$2"
29
+ exit 1
30
+ fi
31
+ }
32
+
33
+ # ----- OS / arch detection ---------------------------------------------------
34
+
35
+ OS=unknown
36
+ ARCH=$(uname -m 2>/dev/null || echo unknown)
37
+
38
+ case "$(uname -s 2>/dev/null || echo unknown)" in
39
+ Darwin) OS=macos ;;
40
+ Linux)
41
+ if grep -qi microsoft /proc/version 2>/dev/null; then
42
+ OS=wsl
43
+ else
44
+ OS=linux
45
+ fi
46
+ ;;
47
+ esac
48
+
49
+ # ----- prerequisites ---------------------------------------------------------
50
+
51
+ require_cmd node "Install Node.js ${REQUIRED_NODE_MAJOR}+ from https://nodejs.org and try again."
52
+ NODE_VERSION=$(node -p "process.versions.node")
53
+ NODE_MAJOR=$(printf '%s' "$NODE_VERSION" | cut -d. -f1)
54
+ if [ "$NODE_MAJOR" -lt "$REQUIRED_NODE_MAJOR" ]; then
55
+ err "Node.js ${REQUIRED_NODE_MAJOR}+ required (found v${NODE_VERSION})."
56
+ err "Tip: nvm install ${REQUIRED_NODE_MAJOR} && nvm use ${REQUIRED_NODE_MAJOR}"
57
+ exit 1
58
+ fi
59
+ require_cmd npm
60
+
61
+ info "Natroc installer"
62
+ info " OS: ${OS} (${ARCH})"
63
+ info " Node: v${NODE_VERSION}"
64
+ info " Method: ${METHOD}"
65
+ info ""
66
+
67
+ # ----- install methods -------------------------------------------------------
68
+
69
+ install_npm() {
70
+ info "Installing ${PACKAGE_NAME} from the npm registry..."
71
+ if ! npm install -g "${PACKAGE_NAME}@latest"; then
72
+ err ""
73
+ err "npm install -g failed. Two common causes:"
74
+ err " 1. Package not published yet — try git mode:"
75
+ err " NATROC_INSTALL_METHOD=git curl -fsSL https://natroc.ai/install.sh | sh"
76
+ err " 2. No write permission to global prefix — use a user-local prefix:"
77
+ err " npm config set prefix \"\$HOME/.local\""
78
+ err " export PATH=\"\$HOME/.local/bin:\$PATH\""
79
+ exit 1
80
+ fi
81
+ }
82
+
83
+ install_git() {
84
+ require_cmd git
85
+
86
+ if [ -d "${SRC_DIR}/.git" ]; then
87
+ info "Updating existing clone in ${SRC_DIR}..."
88
+ (cd "${SRC_DIR}" && git pull --ff-only)
89
+ else
90
+ info "Cloning ${GIT_REPO} into ${SRC_DIR}..."
91
+ mkdir -p "$(dirname "${SRC_DIR}")"
92
+ git clone --depth=1 "${GIT_REPO}" "${SRC_DIR}"
93
+ fi
94
+
95
+ info "Installing dependencies + building (this may take a minute)..."
96
+ (cd "${SRC_DIR}" && npm install && npm run all:build)
97
+
98
+ info "Linking 'natroc' bin globally (via npm link)..."
99
+ (cd "${SRC_DIR}" && npm link)
100
+ }
101
+
102
+ install_tarball() {
103
+ url="${NATROC_TARBALL_URL:-}"
104
+ if [ -z "$url" ]; then
105
+ err "Set NATROC_TARBALL_URL=<url-or-path-to-natroc-x.y.z.tgz> for tarball method."
106
+ exit 1
107
+ fi
108
+ info "Installing from tarball: ${url}"
109
+ npm install -g "${url}"
110
+ }
111
+
112
+ case "${METHOD}" in
113
+ npm) install_npm ;;
114
+ git) install_git ;;
115
+ tarball) install_tarball ;;
116
+ *)
117
+ err "Unknown NATROC_INSTALL_METHOD: ${METHOD}"
118
+ err "Valid values: npm | git | tarball"
119
+ exit 1
120
+ ;;
121
+ esac
122
+
123
+ # ----- post-install hint -----------------------------------------------------
124
+
125
+ info ""
126
+ info "Installed. Next steps:"
127
+ info " natroc setup # initialize ~/.natroc/"
128
+ info " natroc server # run gateway in the foreground"
129
+ info " natroc daemon install # OR install as a system service"
130
+ info " natroc daemon status # inspect the service"
131
+ info ""
132
+ info "Web UI + WebSocket: http://127.0.0.1:18789/"
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "natroc",
3
+ "version": "0.0.1",
4
+ "description": "Ultimate Personal AI Agent that can perform complex tasks and even become a Personal Assistant",
5
+ "type": "module",
6
+ "bin": {
7
+ "natroc": "./server/dist/cli.js"
8
+ },
9
+ "files": [
10
+ "server/dist",
11
+ "ui/dist",
12
+ "install.sh",
13
+ "install.ps1",
14
+ "PLAN.md",
15
+ "README.md",
16
+ "LICENSE",
17
+ "AGENTS.md"
18
+ ],
19
+ "engines": {
20
+ "node": ">=24.0.0"
21
+ },
22
+ "scripts": {
23
+ "ui:clean": "rimraf ui/dist ui/node_modules ui/package-lock.json",
24
+ "ui:install": "cd ui && npm install",
25
+ "ui:build": "cd ui && npm run build",
26
+ "ui:dev": "cd ui && npm run dev",
27
+ "ui:typecheck": "cd ui && npm run typecheck",
28
+ "ui:lint": "cd ui && npm run lint",
29
+ "ui:format": "cd ui && npm run format",
30
+ "server:clean": "rimraf server/dist server/node_modules server/package-lock.json",
31
+ "server:install": "cd server && npm install",
32
+ "server:build": "cd server && npm run build",
33
+ "server:dev": "cd server && npm run dev",
34
+ "server:typecheck": "cd server && npm run typecheck",
35
+ "server:test": "cd server && npm run test",
36
+ "all:clean": "npm run ui:clean && npm run server:clean",
37
+ "all:install": "npm run ui:install && npm run server:install",
38
+ "all:build": "npm run ui:build && npm run server:build",
39
+ "prepublishOnly": "npm run all:install && npm run all:build"
40
+ },
41
+ "dependencies": {
42
+ "@fastify/cors": "^11.2.0",
43
+ "@fastify/websocket": "^11.2.0",
44
+ "@openrouter/agent": "^0.7.0",
45
+ "@openrouter/sdk": "^0.12.35",
46
+ "@whiskeysockets/baileys": "^6.7.23",
47
+ "fastify": "^5.8.5",
48
+ "grammy": "^1.43.0",
49
+ "ollama": "^0.6.3",
50
+ "zod": "^4.4.3"
51
+ },
52
+ "devDependencies": {
53
+ "rimraf": "^6.1.3"
54
+ },
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/Licentora/Natroc.git"
58
+ },
59
+ "keywords": [
60
+ "Natroc",
61
+ "AI Agent",
62
+ "Personal Assistant",
63
+ "Artificial Intelligence",
64
+ "Task Automation",
65
+ "Productivity",
66
+ "Machine Learning",
67
+ "Natural Language Processing",
68
+ "Deep Learning",
69
+ "Intelligent Agent"
70
+ ],
71
+ "author": "Licentora <support@licentora.com>",
72
+ "license": "MIT",
73
+ "bugs": {
74
+ "url": "https://github.com/Licentora/Natroc/issues"
75
+ },
76
+ "homepage": "https://github.com/Licentora/Natroc#readme"
77
+ }
@@ -0,0 +1,71 @@
1
+ import type { ProviderAdapter, ProviderChatMessage, ProviderUsage, ProviderThinkingRequest, ProviderName } from "../providers/types.js";
2
+ import type { ToolContext, ToolMode, ToolRisk } from "./tools/types.js";
3
+ export type AgentToolCallRecord = {
4
+ id: string;
5
+ name: string;
6
+ args: Record<string, unknown>;
7
+ risk: ToolRisk;
8
+ status: "ok" | "error";
9
+ output: string;
10
+ };
11
+ export type AgentLoopEvent = {
12
+ type: "metadata";
13
+ provider: ProviderName;
14
+ model: string;
15
+ } | {
16
+ type: "step";
17
+ index: number;
18
+ } | {
19
+ type: "text";
20
+ delta: string;
21
+ } | {
22
+ type: "reasoning";
23
+ delta: string;
24
+ } | {
25
+ type: "tool_call";
26
+ id: string;
27
+ name: string;
28
+ args: Record<string, unknown>;
29
+ risk: ToolRisk;
30
+ } | {
31
+ type: "tool_result";
32
+ id: string;
33
+ status: "ok" | "error";
34
+ output: string;
35
+ } | {
36
+ type: "done";
37
+ content: string;
38
+ model: string;
39
+ toolCalls: AgentToolCallRecord[];
40
+ usage: ProviderUsage[];
41
+ } | {
42
+ type: "error";
43
+ error: string;
44
+ };
45
+ export type AgentLoopInput = {
46
+ adapter: ProviderAdapter;
47
+ provider: ProviderName;
48
+ baseSystemPrompt: string;
49
+ history: ProviderChatMessage[];
50
+ userMessage: string;
51
+ model?: string;
52
+ thinking?: ProviderThinkingRequest;
53
+ mode: ToolMode;
54
+ context: ToolContext;
55
+ maxIterations?: number;
56
+ };
57
+ /**
58
+ * Runs the agentic ReAct loop: the model is asked to either call a tool (by
59
+ * replying with a JSON object) or to give a final plain-text answer. Tool calls
60
+ * are executed and their results fed back until the model produces a final
61
+ * answer or the iteration cap is reached.
62
+ */
63
+ export declare function runAgentLoop(input: AgentLoopInput): AsyncGenerator<AgentLoopEvent>;
64
+ /**
65
+ * Detects a tool call inside a model reply. Returns null when the reply is a
66
+ * plain-text answer (no JSON object with a `tool` field).
67
+ */
68
+ export declare function parseToolCall(text: string): {
69
+ name: string;
70
+ args: Record<string, unknown>;
71
+ } | null;
@@ -0,0 +1,171 @@
1
+ import { buildToolsPrompt, executeTool, findTool, getAvailableTools, } from "./tools/index.js";
2
+ const DEFAULT_MAX_ITERATIONS = 8;
3
+ const EMPTY_MODEL_RESPONSE_RETRY_PROMPT = [
4
+ "Your previous response contained no user-visible answer and no tool call.",
5
+ "Reply now with either a normal plain-text final answer for the user or exactly one JSON tool call using an available tool.",
6
+ "If the needed tool is unavailable, explain the limitation in plain text and answer as far as you can.",
7
+ ].join("\n");
8
+ const MAX_ITERATIONS_MESSAGE = "I reached the maximum number of agent steps before producing a final answer. Please try again or narrow the request.";
9
+ /**
10
+ * Runs the agentic ReAct loop: the model is asked to either call a tool (by
11
+ * replying with a JSON object) or to give a final plain-text answer. Tool calls
12
+ * are executed and their results fed back until the model produces a final
13
+ * answer or the iteration cap is reached.
14
+ */
15
+ export async function* runAgentLoop(input) {
16
+ const tools = getAvailableTools(input.mode);
17
+ const systemPrompt = `${input.baseSystemPrompt}\n\n${buildToolsPrompt(tools)}`;
18
+ const maxIterations = input.maxIterations ?? DEFAULT_MAX_ITERATIONS;
19
+ const messages = [
20
+ { role: "system", content: systemPrompt },
21
+ ...input.history,
22
+ { role: "user", content: input.userMessage },
23
+ ];
24
+ const toolCalls = [];
25
+ const usage = [];
26
+ let lastModel = input.model ?? "";
27
+ for (let index = 0; index < maxIterations; index += 1) {
28
+ yield { type: "step", index };
29
+ let turnText = "";
30
+ try {
31
+ for await (const event of input.adapter.streamChat({
32
+ message: input.userMessage,
33
+ model: input.model,
34
+ messages,
35
+ thinking: input.thinking,
36
+ })) {
37
+ if (event.type === "metadata") {
38
+ lastModel = event.model;
39
+ yield {
40
+ type: "metadata",
41
+ provider: event.provider,
42
+ model: event.model,
43
+ };
44
+ continue;
45
+ }
46
+ if (event.type === "text") {
47
+ turnText += event.delta;
48
+ yield { type: "text", delta: event.delta };
49
+ continue;
50
+ }
51
+ if (event.type === "reasoning") {
52
+ yield { type: "reasoning", delta: event.delta };
53
+ continue;
54
+ }
55
+ if (event.type === "usage") {
56
+ usage.push(event.usage);
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ yield {
62
+ type: "error",
63
+ error: error instanceof Error ? error.message : "Model request failed.",
64
+ };
65
+ return;
66
+ }
67
+ const trimmedTurnText = turnText.trim();
68
+ if (!trimmedTurnText) {
69
+ messages.push({
70
+ role: "user",
71
+ content: EMPTY_MODEL_RESPONSE_RETRY_PROMPT,
72
+ });
73
+ continue;
74
+ }
75
+ const toolCall = parseToolCall(trimmedTurnText);
76
+ if (!toolCall) {
77
+ yield {
78
+ type: "done",
79
+ content: trimmedTurnText,
80
+ model: lastModel,
81
+ toolCalls,
82
+ usage,
83
+ };
84
+ return;
85
+ }
86
+ messages.push({ role: "assistant", content: trimmedTurnText });
87
+ const callId = crypto.randomUUID();
88
+ const risk = findTool(toolCall.name)?.risk ?? "high";
89
+ yield {
90
+ type: "tool_call",
91
+ id: callId,
92
+ name: toolCall.name,
93
+ args: toolCall.args,
94
+ risk,
95
+ };
96
+ const result = await executeTool(toolCall.name, toolCall.args, input.mode, input.context);
97
+ yield {
98
+ type: "tool_result",
99
+ id: callId,
100
+ status: result.ok ? "ok" : "error",
101
+ output: result.output,
102
+ };
103
+ toolCalls.push({
104
+ id: callId,
105
+ name: toolCall.name,
106
+ args: toolCall.args,
107
+ risk,
108
+ status: result.ok ? "ok" : "error",
109
+ output: result.output,
110
+ });
111
+ messages.push({
112
+ role: "user",
113
+ content: buildToolResultMessage(toolCall.name, result),
114
+ });
115
+ }
116
+ yield {
117
+ type: "done",
118
+ content: MAX_ITERATIONS_MESSAGE,
119
+ model: lastModel,
120
+ toolCalls,
121
+ usage,
122
+ };
123
+ }
124
+ function buildToolResultMessage(name, result) {
125
+ const status = result.ok ? "success" : "error";
126
+ const lines = [`Result of tool "${name}" (${status}):`, result.output];
127
+ if (!result.ok) {
128
+ lines.push("", "The tool did not complete successfully. Do not repeat the same failed tool call unless you change the approach. If you cannot continue without that tool, reply with a plain-text explanation for the user.");
129
+ }
130
+ return lines.join("\n");
131
+ }
132
+ /**
133
+ * Detects a tool call inside a model reply. Returns null when the reply is a
134
+ * plain-text answer (no JSON object with a `tool` field).
135
+ */
136
+ export function parseToolCall(text) {
137
+ const trimmed = text.trim();
138
+ if (!trimmed)
139
+ return null;
140
+ const json = extractJsonObject(trimmed);
141
+ if (!json)
142
+ return null;
143
+ let parsed;
144
+ try {
145
+ parsed = JSON.parse(json);
146
+ }
147
+ catch {
148
+ return null;
149
+ }
150
+ if (!isRecord(parsed))
151
+ return null;
152
+ const name = typeof parsed.tool === "string" ? parsed.tool.trim() : "";
153
+ if (!name)
154
+ return null;
155
+ const args = isRecord(parsed.args) ? parsed.args : {};
156
+ return { name, args };
157
+ }
158
+ function extractJsonObject(value) {
159
+ const fenced = value.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1];
160
+ const raw = (fenced ?? value).trim();
161
+ const first = raw.indexOf("{");
162
+ const last = raw.lastIndexOf("}");
163
+ if (first === -1 || last === -1 || last < first) {
164
+ return null;
165
+ }
166
+ return raw.slice(first, last + 1);
167
+ }
168
+ function isRecord(value) {
169
+ return typeof value === "object" && value !== null && !Array.isArray(value);
170
+ }
171
+ //# sourceMappingURL=agent-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../../src/agent/agent-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type NatrocPaths } from "../config/natroc-home.js";
2
+ import type { ChatRole } from "../providers/types.js";
3
+ import type { AgentMemoryEntry } from "../storage/memory-repository.js";
4
+ export declare const defaultHomeContextFileNames: string[];
5
+ export type HomeContextFile = {
6
+ name: string;
7
+ content: string;
8
+ truncated: boolean;
9
+ };
10
+ export type HomeContext = {
11
+ files: HomeContextFile[];
12
+ };
13
+ export type AgentSystemMemory = Pick<AgentMemoryEntry, "id" | "kind" | "title" | "content">;
14
+ export type AgentConversationRecall = {
15
+ id: string;
16
+ title: string;
17
+ updatedAt: string;
18
+ messages: Array<{
19
+ role: ChatRole;
20
+ content: string;
21
+ createdAt: string;
22
+ }>;
23
+ };
24
+ export declare function loadHomeContext(paths: NatrocPaths | undefined, options?: {
25
+ maxFileCharacters?: number;
26
+ }): Promise<HomeContext>;
27
+ export declare function listHomeContextFiles(paths: NatrocPaths | undefined): Promise<string[]>;
28
+ export declare function resolveHomeFilePath(paths: NatrocPaths, fileName: string): string;
29
+ export declare function buildAgentSystemPrompt(context: HomeContext, memories?: AgentSystemMemory[], conversationThreads?: AgentConversationRecall[]): string;
@@ -0,0 +1,134 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import { isAbsolute, relative, resolve, sep } from "node:path";
3
+ import { natrocHomeFileNames } from "../config/natroc-home.js";
4
+ export const defaultHomeContextFileNames = natrocHomeFileNames;
5
+ export async function loadHomeContext(paths, options = {}) {
6
+ if (!paths) {
7
+ throw new Error("Natroc home path is not configured.");
8
+ }
9
+ const homeDir = resolve(paths.homeDir);
10
+ const maxFileCharacters = options.maxFileCharacters ?? 2400;
11
+ const homeFiles = await listHomeMarkdownFiles(homeDir);
12
+ const files = await Promise.all(homeFiles.map(async ({ absolutePath, name }) => {
13
+ assertInsideHome(homeDir, absolutePath);
14
+ const content = await readOptionalHomeFile(absolutePath);
15
+ if (!content.trim()) {
16
+ return null;
17
+ }
18
+ const truncated = content.length > maxFileCharacters;
19
+ const nextContent = truncated
20
+ ? `${content.slice(0, maxFileCharacters).trimEnd()}\n\n[truncated]`
21
+ : content.trimEnd();
22
+ return {
23
+ name,
24
+ content: nextContent,
25
+ truncated
26
+ };
27
+ }));
28
+ return {
29
+ files: files.filter((file) => Boolean(file))
30
+ };
31
+ }
32
+ export async function listHomeContextFiles(paths) {
33
+ if (!paths)
34
+ return [];
35
+ return (await listHomeMarkdownFiles(resolve(paths.homeDir))).map((file) => file.name);
36
+ }
37
+ export function resolveHomeFilePath(paths, fileName) {
38
+ const homeDir = resolve(paths.homeDir);
39
+ const absolutePath = resolve(homeDir, fileName);
40
+ assertInsideHome(homeDir, absolutePath);
41
+ return absolutePath;
42
+ }
43
+ export function buildAgentSystemPrompt(context, memories = [], conversationThreads = []) {
44
+ const sections = [
45
+ "## Natroc Runtime",
46
+ "You are running inside Natroc, a local-first personal AI agent runtime.",
47
+ "Use the injected home files and approved memory as durable local context.",
48
+ "Do not claim to have changed memory, knowledge, files, services, commits, or processes unless the runtime actually did it."
49
+ ];
50
+ if (context.files.length > 0) {
51
+ sections.push("## Natroc Home");
52
+ for (const file of context.files) {
53
+ sections.push(`### ${file.name}`, file.content);
54
+ }
55
+ }
56
+ if (memories.length > 0) {
57
+ sections.push("## Approved Agent Memory");
58
+ for (const memory of memories) {
59
+ sections.push(formatMemory(memory));
60
+ }
61
+ }
62
+ if (conversationThreads.length > 0) {
63
+ sections.push("## Prior Conversation Threads", "These are bounded snippets from stored Natroc conversations across sessions. Use them as recall of previous threads, while treating Approved Agent Memory and the current user message as higher priority if there is a conflict.");
64
+ for (const thread of conversationThreads) {
65
+ sections.push(formatConversationThread(thread));
66
+ }
67
+ }
68
+ sections.push("## Self Improvement Policy", "You may suggest memory, knowledge, or skill improvements, but they must stay pending until the user approves them.");
69
+ return sections.join("\n\n");
70
+ }
71
+ function formatMemory(memory) {
72
+ return `- [${memory.kind}] ${memory.title} (${memory.id}): ${memory.content}`;
73
+ }
74
+ function formatConversationThread(thread) {
75
+ const lines = [
76
+ `### ${thread.title} (${thread.id}, updated ${thread.updatedAt})`,
77
+ ...thread.messages.map((message) => `- ${message.role.toUpperCase()}: ${message.content}`)
78
+ ];
79
+ return lines.join("\n");
80
+ }
81
+ async function readOptionalHomeFile(path) {
82
+ try {
83
+ return await readFile(path, "utf8");
84
+ }
85
+ catch (error) {
86
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
87
+ return "";
88
+ }
89
+ throw error;
90
+ }
91
+ }
92
+ async function listHomeMarkdownFiles(homeDir) {
93
+ const files = await collectMarkdownFiles(homeDir, homeDir);
94
+ return files.sort((left, right) => left.name.localeCompare(right.name));
95
+ }
96
+ async function collectMarkdownFiles(homeDir, currentDir) {
97
+ const entries = await readdir(currentDir, { withFileTypes: true }).catch((error) => {
98
+ if (error instanceof Error &&
99
+ "code" in error &&
100
+ error.code === "ENOENT") {
101
+ return [];
102
+ }
103
+ throw error;
104
+ });
105
+ const files = [];
106
+ for (const entry of entries) {
107
+ const absolutePath = resolve(currentDir, entry.name);
108
+ assertInsideHome(homeDir, absolutePath);
109
+ if (entry.isDirectory()) {
110
+ files.push(...(await collectMarkdownFiles(homeDir, absolutePath)));
111
+ continue;
112
+ }
113
+ if (!entry.isFile() || !entry.name.toLowerCase().endsWith(".md")) {
114
+ continue;
115
+ }
116
+ files.push({
117
+ absolutePath,
118
+ name: toHomeRelativeName(homeDir, absolutePath)
119
+ });
120
+ }
121
+ return files;
122
+ }
123
+ function toHomeRelativeName(homeDir, absolutePath) {
124
+ return relative(homeDir, absolutePath).split(sep).join("/");
125
+ }
126
+ function assertInsideHome(homeDir, absolutePath) {
127
+ const relativePath = relative(homeDir, absolutePath);
128
+ if (relativePath === "" ||
129
+ (!relativePath.startsWith("..") && !isAbsolute(relativePath))) {
130
+ return;
131
+ }
132
+ throw new Error("Natroc home context can only read files inside home.");
133
+ }
134
+ //# sourceMappingURL=home-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-context.js","sourceRoot":"","sources":["../../src/agent/home-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ProviderAdapter } from "../providers/types.js";
2
+ import type { AgentMemoryKind, CreateProposalInput } from "../storage/memory-repository.js";
3
+ import type { MessageRecord } from "../storage/conversation-repository.js";
4
+ export type ImprovementDraft = CreateProposalInput;
5
+ export declare function parseImprovementProposalResponse(response: string): ImprovementDraft[];
6
+ export declare function buildHeuristicImprovementProposals(input: {
7
+ userMessage: string;
8
+ assistantMessage: string;
9
+ conversationId?: string | null;
10
+ }): ImprovementDraft[];
11
+ export declare function generateImprovementProposals(input: {
12
+ adapter: ProviderAdapter;
13
+ model?: string;
14
+ messages: MessageRecord[];
15
+ conversationId?: string | null;
16
+ }): Promise<{
17
+ sourceConversationId: string | null;
18
+ userId?: string | null;
19
+ kind: AgentMemoryKind;
20
+ title: string;
21
+ content: string;
22
+ reason: string;
23
+ }[]>;