Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion iii-config.docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ workers:
logs_console_output: true
- name: iii-exec
config:
# See iii-config.yaml: watch the shipped artifact, not the source.
watch:
- src/**/*.ts
- dist/**/*.mjs
exec:
- node dist/index.mjs
6 changes: 5 additions & 1 deletion iii-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ workers:
logs_console_output: true
- name: iii-exec
config:
# Watch the shipped artifact, not the source tree. The npm package
# ships only `dist/` — `src/**/*.ts` resolves to nothing for end
# users, and on some platforms an empty watch glob causes iii-exec
# to abort startup before it ever spawns the node child.
watch:
- src/**/*.ts
- dist/**/*.mjs
exec:
- node dist/index.mjs
29 changes: 25 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ const IS_RESET = args.includes("--reset");
const IIPINNED_VERSION =
process.env["AGENTMEMORY_III_VERSION"] || "0.11.2";

// How long the wrapper waits for iii-engine's REST API to start responding
// before giving up and printing the "REST API never responded" error.
// The default 15s is too tight on Windows: iii spawns the `iii-exec` worker
// (`node dist/index.mjs`), which has to reconnect over WebSocket and
// register HTTP triggers before the REST surface answers — and Windows cold
// node startup + native deps regularly push that past 15s. Bumping to 60s
// makes Windows installs work out of the box; AGENTMEMORY_READY_TIMEOUT_MS
// lets users tune it further (e.g. CI containers, slow disks).
const READY_TIMEOUT_MS = (() => {
const raw = process.env["AGENTMEMORY_READY_TIMEOUT_MS"];
if (!raw) return 60000;
const parsed = Number.parseInt(raw, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : 60000;
})();

// Map Node platform/arch → the asset name iii-hq/iii ships under
// https://github.com/iii-hq/iii/releases/download/iii/v<version>/<asset>
function iiiReleaseAsset(): string | null {
Expand Down Expand Up @@ -153,6 +168,10 @@ Environment:
AGENTMEMORY_USE_DOCKER=1 Prefer the bundled docker-compose path over the
native iii-engine binary on first run.
AGENTMEMORY_III_VERSION Override pinned iii-engine version (default ${IIPINNED_VERSION}).
AGENTMEMORY_READY_TIMEOUT_MS How long to wait for iii-engine's REST API to
come up before giving up (default 60000).
Raise on slow disks / CI; lower for fast-fail
smoke tests.

Quick start:
npx @agentmemory/agentmemory # start with local iii-engine or Docker
Expand Down Expand Up @@ -1037,10 +1056,10 @@ async function main() {
const s = p.spinner();
s.start("Waiting for iii-engine to be ready...");

const ready = await waitForEngine(15000);
const ready = await waitForEngine(READY_TIMEOUT_MS);
if (!ready) {
const port = getRestPort();
s.stop("iii-engine did not become ready within 15s");
s.stop(`iii-engine did not become ready within ${Math.round(READY_TIMEOUT_MS / 1000)}s`);

if (startupFailure?.kind === "engine-crashed" || startupFailure?.kind === "docker-crashed") {
p.log.error("The iii-engine process crashed on startup.");
Expand Down Expand Up @@ -1384,10 +1403,12 @@ function buildDoctorEffects(): DoctorEffects {
try {
const started = await startEngine();
if (!started) return { ok: false, message: "startEngine() returned false" };
const ready = await waitForEngine(15000);
const ready = await waitForEngine(READY_TIMEOUT_MS);
return {
ok: ready,
message: ready ? "Engine ready" : "Engine did not become ready within 15s",
message: ready
? "Engine ready"
: `Engine did not become ready within ${Math.round(READY_TIMEOUT_MS / 1000)}s`,
};
} catch (err) {
return {
Expand Down
6 changes: 5 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@ export function loadConfig(): AgentMemoryConfig {
const provider = detectProvider(env);

return {
engineUrl: env["III_ENGINE_URL"] || "ws://localhost:49134",
// Use 127.0.0.1 (not "localhost") so we force IPv4. On Windows,
// `localhost` prefers IPv6 (::1) but iii-engine binds IPv4 only, so
// resolving via "localhost" leads to an ECONNREFUSED reconnect loop
// and the iii-exec worker never registers its HTTP triggers.
engineUrl: env["III_ENGINE_URL"] || "ws://127.0.0.1:49134",
restPort: parseInt(env["III_REST_PORT"] || "3111", 10) || 3111,
streamsPort: parseInt(env["III_STREAMS_PORT"] || "3112", 10) || 3112,
provider,
Expand Down