@maximem/synap-js-sdk 0.1.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.
package/.env.example ADDED
@@ -0,0 +1,47 @@
1
+ # ==============================
2
+ # REQUIRED FOR LIVE SDK CALLS
3
+ # ==============================
4
+ # Synap instance id (from dashboard/login flow)
5
+ SYNAP_INSTANCE_ID=
6
+
7
+ # One-time bootstrap key/token from dashboard.
8
+ # Required on first initialization for a new instance/cert bootstrap.
9
+ # Usually not required after credentials are already stored at ~/.synap/instances/<instance_id>.
10
+ SYNAP_BOOTSTRAP_TOKEN=
11
+ # Alias accepted by JS bridge (same value as SYNAP_BOOTSTRAP_TOKEN)
12
+ SYNAP_BOOTSTRAP_KEY=
13
+
14
+ # Synap HTTP endpoint
15
+ SYNAP_BASE_URL=http://<synap-api-host>:8000
16
+
17
+ # Synap gRPC endpoint
18
+ SYNAP_GRPC_HOST=<synap-grpc-host>
19
+ SYNAP_GRPC_PORT=50051
20
+ SYNAP_GRPC_TLS=false
21
+
22
+ # ==============================
23
+ # OPTIONAL
24
+ # ==============================
25
+ # Managed runtime home used by `synap-js-sdk setup`
26
+ SYNAP_JS_SDK_HOME=/Users/anish/.synap-js-sdk
27
+
28
+ # Optional: override Python binary used by bridge/runtime
29
+ SYNAP_PYTHON_BIN=python3
30
+
31
+ # Setup/install mode for the Python SDK from package indexes
32
+ SYNAP_PY_SDK_PACKAGE=maximem-synap
33
+ SYNAP_PY_SDK_VERSION=
34
+ SYNAP_PYTHON_BOOTSTRAP=python3
35
+
36
+ # ==============================
37
+ # ADVANCED / OPTIONAL
38
+ # ==============================
39
+ # Enable verbose telemetry event tracing in Python SDK
40
+ SYNAP_TELEMETRY_TRACE_EVENTS=
41
+
42
+ # Optional env-credential mode keys (only if Python SDK credentials_source=\"env\")
43
+ SYNAP_API_KEY=
44
+ SYNAP_REFRESH_TOKEN=
45
+ SYNAP_MTLS_CERT_PATH=
46
+ SYNAP_MTLS_KEY_PATH=
47
+ SYNAP_CLIENT_ID=
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # @maximem/synap-js-sdk
2
+
3
+ JavaScript SDK wrapper for the Synap Python SDK.
4
+
5
+ This package gives Node.js apps a normal SDK interface, while internally running a Python bridge process that executes the real `maximem_synap` SDK.
6
+
7
+ ## Why this wrapper exists
8
+
9
+ The Synap Python SDK currently has the full feature surface (gRPC anticipation, ingestion lifecycle, context fetch modes, telemetry hooks). This JS SDK keeps your app code in Node while delegating memory operations to Python.
10
+
11
+ ## Architecture
12
+
13
+ ```text
14
+ Your Node app
15
+ -> @maximem/synap-js-sdk (JS API)
16
+ -> BridgeManager (JSON-RPC over stdin/stdout)
17
+ -> synap_bridge.py
18
+ -> maximem_synap (Python SDK)
19
+ -> Synap API + gRPC
20
+ ```
21
+
22
+ ## Flow and failure map
23
+
24
+ ```text
25
+ [1] App calls createClient()/client.init()
26
+ ->
27
+ [2] BridgeManager resolves python path + bridge path
28
+ -> FAIL A: python not found / bridge file missing
29
+ ->
30
+ [3] Node spawns synap_bridge.py child process
31
+ -> FAIL B: process spawn/runtime error
32
+ ->
33
+ [4] Node sends JSON-RPC "init"
34
+ ->
35
+ [5] Python imports maximem_synap + builds SDK config
36
+ -> FAIL C: maximem_synap not installed in chosen python/venv
37
+ ->
38
+ [6] SDK initialize() + optional gRPC listen
39
+ -> FAIL D: invalid instance/auth OR API/gRPC endpoint unreachable
40
+ ->
41
+ [7] App calls add/search/get/delete
42
+ ->
43
+ [8] Node sends JSON-RPC method
44
+ -> FAIL E: IPC timeout / broken pipe / bridge crash
45
+ ->
46
+ [9] Python executes SDK operation
47
+ -> FAIL F: SDK/server error, bad input, ingestion timeout
48
+ ->
49
+ [10] Python returns JSON result
50
+ ->
51
+ [11] Node resolves promise and returns to app
52
+ ```
53
+
54
+ ## What this means operationally
55
+
56
+ Because this is a wrapper SDK, your deployment must include both runtimes:
57
+
58
+ 1. Node.js (for your app + wrapper)
59
+ 2. Python (for the bridge + Synap Python SDK)
60
+ 3. A virtualenv containing `maximem-synap`
61
+
62
+ This is the main difference versus pure JS SDKs.
63
+
64
+ ## Install
65
+
66
+ ```bash
67
+ npm install @maximem/synap-js-sdk
68
+ ```
69
+
70
+ Then set up the Python runtime used by the wrapper (JS runtime flow):
71
+
72
+ ```bash
73
+ npx synap-js-sdk setup --sdk-version <PY_SDK_VERSION>
74
+ ```
75
+
76
+ If you omit `--sdk-version`, it installs the latest package configured as `maximem-synap`.
77
+ This wrapper installs the Python SDK from package indexes (PyPI by default), not from local source paths.
78
+
79
+ If you want TypeScript support from the start, run:
80
+
81
+ ```bash
82
+ npm install @maximem/synap-js-sdk && npx synap-js-sdk setup --sdk-version <PY_SDK_VERSION> && npx synap-js-sdk setup-ts
83
+ ```
84
+
85
+ ## Quick start in a Node project
86
+
87
+ ```js
88
+ const { createClient } = require('@maximem/synap-js-sdk');
89
+
90
+ const synap = createClient({
91
+ instanceId: process.env.SYNAP_INSTANCE_ID,
92
+ bootstrapToken: process.env.SYNAP_BOOTSTRAP_TOKEN,
93
+ baseUrl: process.env.SYNAP_BASE_URL,
94
+ grpcHost: process.env.SYNAP_GRPC_HOST,
95
+ grpcPort: Number(process.env.SYNAP_GRPC_PORT || 50051),
96
+ grpcUseTls: process.env.SYNAP_GRPC_TLS === 'true',
97
+ });
98
+
99
+ async function run() {
100
+ await synap.init();
101
+
102
+ await synap.addMemory({
103
+ userId: 'user-123',
104
+ messages: [
105
+ { role: 'user', content: 'My name is Alex and I live in Austin.' },
106
+ { role: 'assistant', content: 'Got it.' },
107
+ ],
108
+ });
109
+
110
+ const result = await synap.searchMemory({
111
+ userId: 'user-123',
112
+ query: 'Where does the user live?',
113
+ maxResults: 10,
114
+ });
115
+
116
+ console.log(result);
117
+ await synap.shutdown();
118
+ }
119
+
120
+ run().catch(console.error);
121
+ ```
122
+
123
+ ## API
124
+
125
+ ### `createClient(options)` / `new SynapClient(options)`
126
+
127
+ Options:
128
+
129
+ - `instanceId`: explicit Synap instance id. If omitted, the SDK tries `SYNAP_INSTANCE_ID`, then `~/.synap/instances/*/metadata.json`.
130
+ - `bootstrapToken`: one-time bootstrap token/key (env: `SYNAP_BOOTSTRAP_TOKEN` or `SYNAP_BOOTSTRAP_KEY`). Required on first initialization of a new instance.
131
+ - `baseUrl`, `grpcHost`, `grpcPort`, `grpcUseTls`: Synap endpoints.
132
+ - `pythonBin`: explicit Python path for the bridge.
133
+ - `bridgeScriptPath`: override Python bridge script path.
134
+ - `sdkHome`: home for managed runtime (default `~/.synap-js-sdk`).
135
+ - `venvPath`: override managed venv path.
136
+ - `pythonPackage`: pip package name (default `maximem-synap`).
137
+ - `pythonSdkVersion`: pip version pin.
138
+ - `noDeps`: use pip `--no-deps` during auto setup.
139
+ - `noBuildIsolation`: use pip `--no-build-isolation` during auto setup.
140
+ - `upgrade`: use pip `--upgrade` during auto setup.
141
+ - `forceRecreateVenv`: recreate managed venv during auto setup.
142
+ - `autoSetup`: if `true`, runtime setup is attempted automatically when Python is missing.
143
+
144
+ ### Methods
145
+
146
+ - `init()`
147
+ - `addMemory({ userId, messages })`
148
+ - `searchMemory({ userId, query, maxResults })`
149
+ - `getMemories({ userId })`
150
+ - `deleteMemory({ userId, memoryId })`
151
+ - `shutdown()`
152
+
153
+ ## CLI
154
+
155
+ ```bash
156
+ synap-js-sdk setup [options]
157
+ synap-js-sdk setup-ts [options]
158
+ ```
159
+
160
+ Options:
161
+
162
+ `setup`:
163
+ - `--python <bin>`: bootstrap Python command (default `python3`)
164
+ - `--sdk-home <path>`: runtime home directory
165
+ - `--venv <path>`: virtualenv path
166
+ - `--package <name>`: Python package name
167
+ - `--sdk-version <ver>`: Python SDK version pin
168
+ - `--no-deps`: install package with no dependency resolution
169
+ - `--no-build-isolation`: disable pip build isolation
170
+ - `--upgrade`: use pip `--upgrade`
171
+ - `--force-recreate-venv`: recreate venv
172
+
173
+ `setup-ts`:
174
+ - `--project-dir <path>`: target Node project (default: current working directory)
175
+ - `--package-manager <name>`: one of `npm`, `pnpm`, `yarn`, `bun` (auto-detected by lockfile if omitted)
176
+ - `--skip-install`: skip TypeScript dependency install (`typescript`, `@types/node`)
177
+ - `--tsconfig-path <path>`: output path for generated tsconfig (default: `tsconfig.json`)
178
+ - `--wrapper-path <path>`: output path for generated typed wrapper (default: `src/synap.ts`)
179
+ - `--no-wrapper`: do not generate typed wrapper file
180
+ - `--force`: overwrite generated files if they already exist
181
+
182
+ ## TypeScript Extension Flow
183
+
184
+ Use this when a project already has `@maximem/synap-js-sdk` installed and wants type safety without rewriting runtime JS:
185
+
186
+ 1. Run `npx synap-js-sdk setup-ts`
187
+ 2. This installs `typescript` and `@types/node` (unless `--skip-install`)
188
+ 3. This generates `tsconfig.json` (if missing)
189
+ 4. This generates `src/synap.ts` typed wrapper (unless `--no-wrapper`)
190
+
191
+ Programmatic alternative:
192
+
193
+ ```js
194
+ const { setupTypeScriptExtension } = require('@maximem/synap-js-sdk');
195
+
196
+ setupTypeScriptExtension({ projectDir: process.cwd() });
197
+ ```
198
+
199
+ ## Environment template
200
+
201
+ Use the provided template:
202
+
203
+ ```bash
204
+ cp .env.example .env
205
+ ```
206
+
207
+ Template file: `.env.example`
208
+
209
+ ## EC2 + Docker flow (recommended)
210
+
211
+ Build time should install Node deps and Python runtime once, not on every container start.
212
+
213
+ ```dockerfile
214
+ FROM node:20-bullseye
215
+
216
+ RUN apt-get update && apt-get install -y python3 python3-venv && rm -rf /var/lib/apt/lists/*
217
+
218
+ WORKDIR /app
219
+ COPY package*.json ./
220
+ RUN npm ci
221
+
222
+ # Install wrapper python runtime deterministically
223
+ RUN npx synap-js-sdk setup --python python3 --sdk-home /opt/synap-js-sdk --sdk-version <PY_SDK_VERSION>
224
+
225
+ COPY . .
226
+
227
+ ENV SYNAP_JS_SDK_HOME=/opt/synap-js-sdk
228
+ ENV SYNAP_BASE_URL=http://<synap-api-host>:8000
229
+ ENV SYNAP_GRPC_HOST=<synap-grpc-host>
230
+ ENV SYNAP_GRPC_PORT=50051
231
+ ENV SYNAP_GRPC_TLS=false
232
+
233
+ CMD ["node", "server.js"]
234
+ ```
235
+
236
+ Runtime flow in container:
237
+
238
+ 1. Node app starts.
239
+ 2. First Synap call starts Python bridge process.
240
+ 3. Bridge sends `init` to Python SDK.
241
+ 4. API methods run through JSON-RPC.
242
+ 5. On shutdown, wrapper sends `shutdown` and stops bridge.
243
+
244
+ ## Versioning and compatibility matrix
245
+
246
+ Recommended policy:
247
+
248
+ 1. Keep JS and Python SDK on the same semantic version (`x.y.z`).
249
+ 2. Publish JS only after Python package `x.y.z` is available.
250
+ 3. CI release pipeline should verify `pip install maximem-synap==x.y.z` before npm publish.
251
+
252
+ Even with same-version policy, keep a compatibility table in docs for rollback safety:
253
+
254
+ ```text
255
+ JS 1.3.x -> Python 1.3.x
256
+ JS 1.2.x -> Python 1.2.x
257
+ ```
258
+
259
+ ## Failure modes to expect
260
+
261
+ - Python not installed or not found
262
+ - Bridge process crash/restart
263
+ - pip install failure due to network/private index
264
+ - auth/instance id missing or expired
265
+
266
+ Treat this SDK as a managed dual-runtime component in production.
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { setupPythonRuntime } = require('../src/runtime');
4
+ const { setupTypeScriptExtension } = require('../src/setup-typescript');
5
+
6
+ function parseArgs(argv) {
7
+ const args = { _: [] };
8
+
9
+ for (let i = 0; i < argv.length; i += 1) {
10
+ const token = argv[i];
11
+
12
+ if (!token.startsWith('--')) {
13
+ args._.push(token);
14
+ continue;
15
+ }
16
+
17
+ const key = token.slice(2);
18
+ const next = argv[i + 1];
19
+
20
+ if (!next || next.startsWith('--')) {
21
+ args[key] = true;
22
+ continue;
23
+ }
24
+
25
+ args[key] = next;
26
+ i += 1;
27
+ }
28
+
29
+ return args;
30
+ }
31
+
32
+ function printHelp() {
33
+ console.log(`synap-js-sdk
34
+
35
+ Usage:
36
+ synap-js-sdk setup [options]
37
+ synap-js-sdk setup-ts [options]
38
+
39
+ setup options:
40
+ --python <bin> Python bootstrap binary (default: python3)
41
+ --sdk-home <path> SDK home (default: ~/.synap-js-sdk)
42
+ --venv <path> Virtualenv path (default: <sdk-home>/.venv)
43
+ --package <name> Python package name (default: maximem-synap)
44
+ --sdk-version <ver> Python SDK version to install
45
+ --no-deps Install without dependencies
46
+ --no-build-isolation Disable pip build isolation
47
+ --upgrade Use pip --upgrade
48
+ --force-recreate-venv Recreate virtualenv
49
+
50
+ setup-ts options:
51
+ --project-dir <path> Target Node project directory (default: cwd)
52
+ --package-manager <name> npm | pnpm | yarn | bun (auto-detect if omitted)
53
+ --skip-install Skip installing typescript and @types/node
54
+ --tsconfig-path <path> tsconfig output path (default: tsconfig.json)
55
+ --wrapper-path <path> Typed wrapper output path (default: src/synap.ts)
56
+ --no-wrapper Do not generate the typed wrapper file
57
+ --force Overwrite generated files when they already exist
58
+
59
+ global:
60
+ --help Show this help
61
+ `);
62
+ }
63
+
64
+ async function run() {
65
+ const args = parseArgs(process.argv.slice(2));
66
+ const command = args._[0];
67
+
68
+ if (!command || args.help || command === 'help') {
69
+ printHelp();
70
+ process.exit(0);
71
+ }
72
+
73
+ if (command === 'setup') {
74
+ try {
75
+ const result = await setupPythonRuntime({
76
+ pythonBootstrap: args.python,
77
+ sdkHome: args['sdk-home'],
78
+ venvPath: args.venv,
79
+ pythonPackage: args.package,
80
+ pythonSdkVersion: args['sdk-version'],
81
+ noDeps: !!args['no-deps'],
82
+ noBuildIsolation: !!args['no-build-isolation'],
83
+ upgrade: !!args.upgrade,
84
+ forceRecreateVenv: !!args['force-recreate-venv'],
85
+ });
86
+
87
+ console.log('Synap JS SDK Python runtime setup complete.');
88
+ console.log(JSON.stringify(result, null, 2));
89
+ return;
90
+ } catch (error) {
91
+ console.error('Setup failed:');
92
+ console.error(error.message || String(error));
93
+ process.exit(1);
94
+ }
95
+ }
96
+
97
+ if (command === 'setup-ts') {
98
+ try {
99
+ const result = await setupTypeScriptExtension({
100
+ projectDir: args['project-dir'],
101
+ packageManager: args['package-manager'],
102
+ skipInstall: !!args['skip-install'],
103
+ tsconfigPath: args['tsconfig-path'],
104
+ wrapperPath: args['wrapper-path'],
105
+ noWrapper: !!args['no-wrapper'],
106
+ force: !!args.force,
107
+ });
108
+
109
+ console.log('Synap JS SDK TypeScript extension setup complete.');
110
+ console.log(JSON.stringify(result, null, 2));
111
+ return;
112
+ } catch (error) {
113
+ console.error('TypeScript setup failed:');
114
+ console.error(error.message || String(error));
115
+ process.exit(1);
116
+ }
117
+ }
118
+
119
+ console.error(`Unknown command: ${command}`);
120
+ printHelp();
121
+ process.exit(1);
122
+ }
123
+
124
+ run();