cogspace 0.3.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/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # @cogspace/sdk
2
+
3
+ Official TypeScript SDK for [Cogspace](https://cogspace.ai) — persistent knowledge layer for AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @cogspace/sdk
9
+ # or
10
+ pnpm add @cogspace/sdk
11
+ # or
12
+ bun add @cogspace/sdk
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```typescript
18
+ import { Cogspace } from "@cogspace/sdk";
19
+
20
+ // Reads COGSPACE_API_KEY from environment automatically
21
+ const cog = new Cogspace();
22
+ const space = await cog.space("my-agent");
23
+
24
+ // See what exists
25
+ const files = await space.list("expertise");
26
+ console.log(`${files.file_count} files`);
27
+
28
+ // Add knowledge
29
+ await space.add(
30
+ "expertise/retry.md",
31
+ "# Retry Patterns\nUse exponential backoff with jitter.",
32
+ "expertise",
33
+ "retry-patterns",
34
+ { confidence: 0.95 }
35
+ );
36
+
37
+ // Search
38
+ const results = await space.search("retry logic", { limit: 5 });
39
+ for (const item of results.results) {
40
+ console.log(`${item.path}: ${item.score}`);
41
+ }
42
+
43
+ // Retrieve a file
44
+ const file = await space.retrieve("expertise/retry.md");
45
+ console.log(file.content);
46
+
47
+ // Delete
48
+ await space.forget("expertise/retry.md");
49
+ ```
50
+
51
+ ## Works everywhere
52
+
53
+ Native `fetch` — no dependencies. Works in Node 18+, Deno, Bun, Edge, browser.
54
+
55
+ ## API Reference
56
+
57
+ ### `new Cogspace(config?)`
58
+
59
+ Reads `COGSPACE_API_KEY` from environment if `apiKey` not provided.
60
+
61
+ | Option | Default | Description |
62
+ |---|---|---|
63
+ | `apiKey` | env `COGSPACE_API_KEY` | Your API key |
64
+ | `baseUrl` | `https://platform.cogspace.ai` | Platform URL |
65
+ | `timeout` | `30000` | Request timeout (ms) |
66
+ | `maxRetries` | `3` | Retries on 429/5xx |
67
+
68
+ ### `cog.space(nameOrId)` → `SpaceClient`
69
+
70
+ | Method | Description |
71
+ |---|---|
72
+ | `space.list(folder?)` | List files in folder |
73
+ | `space.retrieve(path)` | Get one file |
74
+ | `space.search(query, options?)` | Search all layers |
75
+ | `space.add(path, content, layer, topic, options?)` | Add/update knowledge |
76
+ | `space.forget(path)` | Delete from all layers |
77
+
78
+ #### `add()` parameters
79
+
80
+ ```typescript
81
+ space.add(
82
+ "expertise/retry.md", // path
83
+ "# Retry\nUse backoff...", // content
84
+ "expertise", // layer: "expertise" | "memory" | "root"
85
+ "retry-patterns", // topic
86
+ {
87
+ confidence: 0.95, // 0.0-1.0, default 0.9
88
+ relates_to: ["error.md"], // related files
89
+ }
90
+ )
91
+ ```
92
+
93
+ ## Errors
94
+
95
+ ```typescript
96
+ import { AuthError, NotFoundError, LimitExceededError } from "@cogspace/sdk";
97
+
98
+ try {
99
+ await space.search("query", { limit: 200 });
100
+ } catch (err) {
101
+ if (err instanceof LimitExceededError) console.error("Max limit is 100");
102
+ if (err instanceof AuthError) console.error("Invalid API key");
103
+ if (err instanceof NotFoundError) console.error("Space not found");
104
+ }
105
+ ```
106
+
107
+ ## Get an API key
108
+
109
+ Sign in at [platform.cogspace.ai](https://platform.cogspace.ai) → **Settings → API keys** → **Create key**.
package/dist/index.cjs ADDED
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthError: () => AuthError,
24
+ Cogspace: () => Cogspace,
25
+ CogspaceError: () => CogspaceError,
26
+ HttpClient: () => HttpClient,
27
+ LimitExceededError: () => LimitExceededError,
28
+ NotFoundError: () => NotFoundError,
29
+ RateLimitError: () => RateLimitError,
30
+ ServerError: () => ServerError,
31
+ SpaceClient: () => SpaceClient,
32
+ TimeoutError: () => TimeoutError
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/errors.ts
37
+ var CogspaceError = class extends Error {
38
+ constructor(message, status, code) {
39
+ super(message);
40
+ this.name = "CogspaceError";
41
+ this.status = status;
42
+ this.code = code;
43
+ }
44
+ };
45
+ var AuthError = class extends CogspaceError {
46
+ constructor(message, status) {
47
+ super(message, status);
48
+ this.name = "AuthError";
49
+ }
50
+ };
51
+ var NotFoundError = class extends CogspaceError {
52
+ constructor(message, status) {
53
+ super(message, status);
54
+ this.name = "NotFoundError";
55
+ }
56
+ };
57
+ var RateLimitError = class extends CogspaceError {
58
+ constructor(message, status) {
59
+ super(message, status);
60
+ this.name = "RateLimitError";
61
+ }
62
+ };
63
+ var ServerError = class extends CogspaceError {
64
+ constructor(message, status) {
65
+ super(message, status);
66
+ this.name = "ServerError";
67
+ }
68
+ };
69
+ var TimeoutError = class extends CogspaceError {
70
+ constructor(message) {
71
+ super(message);
72
+ this.name = "TimeoutError";
73
+ }
74
+ };
75
+ var LimitExceededError = class extends CogspaceError {
76
+ constructor(message) {
77
+ super(message);
78
+ this.name = "LimitExceededError";
79
+ }
80
+ };
81
+ function raiseForStatus(status, body) {
82
+ const message = String(body.detail ?? body.message ?? `HTTP ${status}`);
83
+ const code = body.error;
84
+ if (status === 401) throw new AuthError(message, status);
85
+ if (status === 404) throw new NotFoundError(message, status);
86
+ if (status === 429) throw new RateLimitError(message, status);
87
+ if (status >= 500) throw new ServerError(message, status);
88
+ throw new CogspaceError(message, status, code);
89
+ }
90
+
91
+ // src/client.ts
92
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
93
+ var HttpClient = class {
94
+ constructor(config = {}) {
95
+ const envKey = typeof process !== "undefined" && process.env ? process.env["COGSPACE_API_KEY"] : void 0;
96
+ const key = config.apiKey ?? envKey ?? "";
97
+ if (!key) {
98
+ throw new Error(
99
+ "API key is required. Pass apiKey: in config or set the COGSPACE_API_KEY environment variable."
100
+ );
101
+ }
102
+ this.apiKey = key;
103
+ this.baseUrl = (config.baseUrl ?? "https://platform.cogspace.ai").replace(/\/$/, "");
104
+ this.timeout = config.timeout ?? 3e4;
105
+ this.maxRetries = config.maxRetries ?? 3;
106
+ }
107
+ headers() {
108
+ return {
109
+ Authorization: `Bearer ${this.apiKey}`,
110
+ "Content-Type": "application/json",
111
+ "User-Agent": "cogspace-ts/0.2.0"
112
+ };
113
+ }
114
+ async request(method, path, body, params) {
115
+ let url = `${this.baseUrl}${path}`;
116
+ if (params && Object.keys(params).length > 0) {
117
+ url += "?" + new URLSearchParams(params).toString();
118
+ }
119
+ let lastError;
120
+ for (let attempt = 0; attempt < this.maxRetries; attempt++) {
121
+ const controller = new AbortController();
122
+ const timer = setTimeout(() => controller.abort(), this.timeout);
123
+ let response;
124
+ try {
125
+ response = await fetch(url, {
126
+ method,
127
+ headers: this.headers(),
128
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
129
+ signal: controller.signal
130
+ });
131
+ } catch (err) {
132
+ clearTimeout(timer);
133
+ if (err instanceof Error && err.name === "AbortError") {
134
+ throw new TimeoutError(`Request timed out: ${path}`);
135
+ }
136
+ throw err;
137
+ }
138
+ clearTimeout(timer);
139
+ if (!RETRY_STATUSES.has(response.status)) {
140
+ if (response.status >= 400) {
141
+ let errBody = {};
142
+ try {
143
+ errBody = await response.json();
144
+ } catch {
145
+ }
146
+ raiseForStatus(response.status, errBody);
147
+ }
148
+ if (response.status === 204 || response.headers.get("content-length") === "0") {
149
+ return void 0;
150
+ }
151
+ return response.json();
152
+ }
153
+ if (attempt < this.maxRetries - 1) {
154
+ let wait = Math.pow(2, attempt) * 1e3;
155
+ const retryAfter = response.headers.get("Retry-After");
156
+ if (retryAfter) wait = parseFloat(retryAfter) * 1e3;
157
+ await new Promise((r) => setTimeout(r, wait));
158
+ let errBody = {};
159
+ try {
160
+ errBody = await response.json();
161
+ } catch {
162
+ }
163
+ lastError = new RateLimitError(String(errBody.detail ?? `HTTP ${response.status}`), response.status);
164
+ } else {
165
+ let errBody = {};
166
+ try {
167
+ errBody = await response.json();
168
+ } catch {
169
+ }
170
+ raiseForStatus(response.status, errBody);
171
+ }
172
+ }
173
+ throw lastError ?? new RateLimitError("Max retries exceeded");
174
+ }
175
+ get(path, params) {
176
+ return this.request("GET", path, void 0, params);
177
+ }
178
+ post(path, body) {
179
+ return this.request("POST", path, body);
180
+ }
181
+ delete(path, params) {
182
+ return this.request("DELETE", path, void 0, params);
183
+ }
184
+ };
185
+
186
+ // src/space.ts
187
+ var MAX_LIMIT = 100;
188
+ var SpaceClient = class {
189
+ constructor(client, spaceId) {
190
+ this.client = client;
191
+ this.spaceId = spaceId;
192
+ }
193
+ path(endpoint) {
194
+ return `/spaces/${this.spaceId}/${endpoint}`;
195
+ }
196
+ /**
197
+ * List all files in a folder.
198
+ * @param folder - Folder to list (e.g. "expertise"). Empty = entire space.
199
+ */
200
+ list(folder = "") {
201
+ return this.client.get(this.path("list"), { folder });
202
+ }
203
+ /**
204
+ * Retrieve a single file by path.
205
+ * @param path - Relative file path (e.g. "expertise/retry.md").
206
+ */
207
+ retrieve(path) {
208
+ return this.client.get(this.path("retrieve"), { path });
209
+ }
210
+ /**
211
+ * Search all layers (vectors + BM25 + knowledge graph).
212
+ * @param query - What to search for.
213
+ * @param options.limit - Max results. Default 10, max 100.
214
+ * @param options.layer - Optional filter: "expertise", "memory", or "root".
215
+ */
216
+ async search(query, options = {}) {
217
+ const limit = options.limit ?? 10;
218
+ if (limit > MAX_LIMIT) {
219
+ throw new LimitExceededError(`limit must be <= ${MAX_LIMIT}. Got: ${limit}`);
220
+ }
221
+ return this.client.post(this.path("search"), {
222
+ query,
223
+ limit,
224
+ layer: options.layer ?? null
225
+ });
226
+ }
227
+ /**
228
+ * Add or update knowledge. All layers updated automatically.
229
+ * @param path - Where to write (e.g. "expertise/retry.md").
230
+ * @param content - Markdown content.
231
+ * @param layer - "expertise", "memory", or "root".
232
+ * @param topic - Category/topic for this knowledge.
233
+ * @param options.confidence - How certain (0.0-1.0). Default 0.9.
234
+ * @param options.relates_to - Related file names.
235
+ */
236
+ add(path, content, layer, topic, options = {}) {
237
+ return this.client.post(this.path("add"), {
238
+ path,
239
+ content,
240
+ layer,
241
+ topic,
242
+ confidence: options.confidence ?? 0.9,
243
+ relates_to: options.relates_to ?? null,
244
+ agent_id: options.agent_id ?? "default"
245
+ });
246
+ }
247
+ /**
248
+ * Delete knowledge from all layers (cascading).
249
+ * @param path - Relative file path to delete.
250
+ */
251
+ forget(path) {
252
+ return this.client.delete(this.path("forget"), { path });
253
+ }
254
+ };
255
+
256
+ // src/index.ts
257
+ var Cogspace = class {
258
+ constructor(config = {}) {
259
+ this.spaceCache = /* @__PURE__ */ new Map();
260
+ this.client = new HttpClient(config);
261
+ }
262
+ async resolveSpaceId(nameOrId) {
263
+ const cached = this.spaceCache.get(nameOrId);
264
+ if (cached) return cached;
265
+ const spaces = await this.client.get("/spaces");
266
+ for (const s of spaces) {
267
+ this.spaceCache.set(s.name, s.id);
268
+ this.spaceCache.set(s.id, s.id);
269
+ if (s.name === nameOrId || s.id === nameOrId) {
270
+ return s.id;
271
+ }
272
+ }
273
+ throw new NotFoundError(`Space not found: ${nameOrId}`);
274
+ }
275
+ /** Get a space-scoped client by name or ID. */
276
+ async space(nameOrId) {
277
+ const spaceId = await this.resolveSpaceId(nameOrId);
278
+ return new SpaceClient(this.client, spaceId);
279
+ }
280
+ /** List all your spaces. */
281
+ listSpaces() {
282
+ return this.client.get("/spaces");
283
+ }
284
+ /** Create a new space. */
285
+ createSpace(name) {
286
+ return this.client.post("/spaces", { name });
287
+ }
288
+ };
289
+ // Annotate the CommonJS export names for ESM import in node:
290
+ 0 && (module.exports = {
291
+ AuthError,
292
+ Cogspace,
293
+ CogspaceError,
294
+ HttpClient,
295
+ LimitExceededError,
296
+ NotFoundError,
297
+ RateLimitError,
298
+ ServerError,
299
+ SpaceClient,
300
+ TimeoutError
301
+ });
@@ -0,0 +1,201 @@
1
+ /** HTTP client for the Cogspace TypeScript SDK. Zero dependencies — native fetch. */
2
+ interface ClientConfig {
3
+ apiKey?: string;
4
+ baseUrl?: string;
5
+ timeout?: number;
6
+ maxRetries?: number;
7
+ }
8
+ declare class HttpClient {
9
+ private readonly apiKey;
10
+ private readonly baseUrl;
11
+ private readonly timeout;
12
+ private readonly maxRetries;
13
+ constructor(config?: ClientConfig);
14
+ private headers;
15
+ private request;
16
+ get<T>(path: string, params?: Record<string, string>): Promise<T>;
17
+ post<T>(path: string, body?: unknown): Promise<T>;
18
+ delete<T>(path: string, params?: Record<string, string>): Promise<T>;
19
+ }
20
+
21
+ /** Response types for the Cogspace TypeScript SDK v0.2.0 */
22
+ /** A knowledge graph edge attached to a search result. */
23
+ interface GraphRelation {
24
+ path: string;
25
+ rel_type: "IMPLEMENTS" | "EXTENDS" | "AVOIDS" | "CONFLICTS" | "REFERENCES";
26
+ topic: string;
27
+ layer: string;
28
+ }
29
+ interface SearchItem {
30
+ path: string;
31
+ content: string;
32
+ score: number;
33
+ layer: string;
34
+ confidence: number;
35
+ /** Knowledge graph neighbors — empty if graph unavailable or file has no edges. */
36
+ related: GraphRelation[];
37
+ }
38
+ interface SearchResponse {
39
+ results: SearchItem[];
40
+ total: number;
41
+ query: string;
42
+ mode: string;
43
+ }
44
+ interface ReadResponse {
45
+ path: string;
46
+ content: string;
47
+ layer: string;
48
+ size_bytes: number;
49
+ frontmatter: Record<string, unknown>;
50
+ }
51
+ interface WriteResponse {
52
+ path: string;
53
+ status: "created" | "updated";
54
+ reindex_queued: boolean;
55
+ }
56
+ interface ListResponse {
57
+ tree: Record<string, unknown>;
58
+ file_count: number;
59
+ folder: string;
60
+ }
61
+ interface Space {
62
+ id: string;
63
+ user_id: string;
64
+ name: string;
65
+ created_at: string;
66
+ }
67
+ interface SearchOptions {
68
+ limit?: number;
69
+ layer?: string;
70
+ }
71
+ interface AddOptions {
72
+ confidence?: number;
73
+ relates_to?: string[];
74
+ agent_id?: string;
75
+ }
76
+
77
+ /** SpaceClient — all operations scoped to a single Cogspace space. */
78
+
79
+ declare class SpaceClient {
80
+ private readonly client;
81
+ readonly spaceId: string;
82
+ constructor(client: HttpClient, spaceId: string);
83
+ private path;
84
+ /**
85
+ * List all files in a folder.
86
+ * @param folder - Folder to list (e.g. "expertise"). Empty = entire space.
87
+ */
88
+ list(folder?: string): Promise<ListResponse>;
89
+ /**
90
+ * Retrieve a single file by path.
91
+ * @param path - Relative file path (e.g. "expertise/retry.md").
92
+ */
93
+ retrieve(path: string): Promise<ReadResponse>;
94
+ /**
95
+ * Search all layers (vectors + BM25 + knowledge graph).
96
+ * @param query - What to search for.
97
+ * @param options.limit - Max results. Default 10, max 100.
98
+ * @param options.layer - Optional filter: "expertise", "memory", or "root".
99
+ */
100
+ search(query: string, options?: SearchOptions): Promise<SearchResponse>;
101
+ /**
102
+ * Add or update knowledge. All layers updated automatically.
103
+ * @param path - Where to write (e.g. "expertise/retry.md").
104
+ * @param content - Markdown content.
105
+ * @param layer - "expertise", "memory", or "root".
106
+ * @param topic - Category/topic for this knowledge.
107
+ * @param options.confidence - How certain (0.0-1.0). Default 0.9.
108
+ * @param options.relates_to - Related file names.
109
+ */
110
+ add(path: string, content: string, layer: "expertise" | "memory" | "root", topic: string, options?: AddOptions): Promise<WriteResponse>;
111
+ /**
112
+ * Delete knowledge from all layers (cascading).
113
+ * @param path - Relative file path to delete.
114
+ */
115
+ forget(path: string): Promise<void>;
116
+ }
117
+
118
+ /** Cogspace SDK error hierarchy. */
119
+ declare class CogspaceError extends Error {
120
+ readonly status: number | undefined;
121
+ readonly code: string | undefined;
122
+ constructor(message: string, status?: number, code?: string);
123
+ }
124
+ declare class AuthError extends CogspaceError {
125
+ constructor(message: string, status?: number);
126
+ }
127
+ declare class NotFoundError extends CogspaceError {
128
+ constructor(message: string, status?: number);
129
+ }
130
+ declare class RateLimitError extends CogspaceError {
131
+ constructor(message: string, status?: number);
132
+ }
133
+ declare class ServerError extends CogspaceError {
134
+ constructor(message: string, status?: number);
135
+ }
136
+ declare class TimeoutError extends CogspaceError {
137
+ constructor(message: string);
138
+ }
139
+ declare class LimitExceededError extends CogspaceError {
140
+ constructor(message: string);
141
+ }
142
+
143
+ /**
144
+ * Cogspace TypeScript SDK v0.2.0 — persistent knowledge layer for AI agents.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * import { Cogspace } from "@cogspace/sdk";
149
+ *
150
+ * // Reads COGSPACE_API_KEY from environment
151
+ * const cog = new Cogspace();
152
+ * const space = await cog.space("my-agent");
153
+ *
154
+ * // See what exists
155
+ * const files = await space.list("expertise");
156
+ *
157
+ * // Add knowledge
158
+ * await space.add(
159
+ * "expertise/retry.md",
160
+ * "# Retry Patterns\nUse exponential backoff...",
161
+ * "expertise",
162
+ * "retry-patterns",
163
+ * { confidence: 0.95 }
164
+ * );
165
+ *
166
+ * // Search
167
+ * const results = await space.search("retry logic", { limit: 5 });
168
+ *
169
+ * // Retrieve a file
170
+ * const file = await space.retrieve("expertise/retry.md");
171
+ *
172
+ * // Delete
173
+ * await space.forget("expertise/retry.md");
174
+ * ```
175
+ */
176
+
177
+ interface CogspaceConfig extends ClientConfig {
178
+ apiKey?: string;
179
+ baseUrl?: string;
180
+ timeout?: number;
181
+ maxRetries?: number;
182
+ }
183
+ /**
184
+ * Cogspace client. Instantiate once per process and reuse.
185
+ *
186
+ * Reads COGSPACE_API_KEY from environment automatically.
187
+ */
188
+ declare class Cogspace {
189
+ private readonly client;
190
+ private readonly spaceCache;
191
+ constructor(config?: CogspaceConfig);
192
+ private resolveSpaceId;
193
+ /** Get a space-scoped client by name or ID. */
194
+ space(nameOrId: string): Promise<SpaceClient>;
195
+ /** List all your spaces. */
196
+ listSpaces(): Promise<Space[]>;
197
+ /** Create a new space. */
198
+ createSpace(name: string): Promise<Space>;
199
+ }
200
+
201
+ export { type AddOptions, AuthError, Cogspace, type CogspaceConfig, CogspaceError, HttpClient, LimitExceededError, type ListResponse, NotFoundError, RateLimitError, type ReadResponse, type SearchItem, type SearchOptions, type SearchResponse, ServerError, type Space, SpaceClient, TimeoutError, type WriteResponse };
@@ -0,0 +1,201 @@
1
+ /** HTTP client for the Cogspace TypeScript SDK. Zero dependencies — native fetch. */
2
+ interface ClientConfig {
3
+ apiKey?: string;
4
+ baseUrl?: string;
5
+ timeout?: number;
6
+ maxRetries?: number;
7
+ }
8
+ declare class HttpClient {
9
+ private readonly apiKey;
10
+ private readonly baseUrl;
11
+ private readonly timeout;
12
+ private readonly maxRetries;
13
+ constructor(config?: ClientConfig);
14
+ private headers;
15
+ private request;
16
+ get<T>(path: string, params?: Record<string, string>): Promise<T>;
17
+ post<T>(path: string, body?: unknown): Promise<T>;
18
+ delete<T>(path: string, params?: Record<string, string>): Promise<T>;
19
+ }
20
+
21
+ /** Response types for the Cogspace TypeScript SDK v0.2.0 */
22
+ /** A knowledge graph edge attached to a search result. */
23
+ interface GraphRelation {
24
+ path: string;
25
+ rel_type: "IMPLEMENTS" | "EXTENDS" | "AVOIDS" | "CONFLICTS" | "REFERENCES";
26
+ topic: string;
27
+ layer: string;
28
+ }
29
+ interface SearchItem {
30
+ path: string;
31
+ content: string;
32
+ score: number;
33
+ layer: string;
34
+ confidence: number;
35
+ /** Knowledge graph neighbors — empty if graph unavailable or file has no edges. */
36
+ related: GraphRelation[];
37
+ }
38
+ interface SearchResponse {
39
+ results: SearchItem[];
40
+ total: number;
41
+ query: string;
42
+ mode: string;
43
+ }
44
+ interface ReadResponse {
45
+ path: string;
46
+ content: string;
47
+ layer: string;
48
+ size_bytes: number;
49
+ frontmatter: Record<string, unknown>;
50
+ }
51
+ interface WriteResponse {
52
+ path: string;
53
+ status: "created" | "updated";
54
+ reindex_queued: boolean;
55
+ }
56
+ interface ListResponse {
57
+ tree: Record<string, unknown>;
58
+ file_count: number;
59
+ folder: string;
60
+ }
61
+ interface Space {
62
+ id: string;
63
+ user_id: string;
64
+ name: string;
65
+ created_at: string;
66
+ }
67
+ interface SearchOptions {
68
+ limit?: number;
69
+ layer?: string;
70
+ }
71
+ interface AddOptions {
72
+ confidence?: number;
73
+ relates_to?: string[];
74
+ agent_id?: string;
75
+ }
76
+
77
+ /** SpaceClient — all operations scoped to a single Cogspace space. */
78
+
79
+ declare class SpaceClient {
80
+ private readonly client;
81
+ readonly spaceId: string;
82
+ constructor(client: HttpClient, spaceId: string);
83
+ private path;
84
+ /**
85
+ * List all files in a folder.
86
+ * @param folder - Folder to list (e.g. "expertise"). Empty = entire space.
87
+ */
88
+ list(folder?: string): Promise<ListResponse>;
89
+ /**
90
+ * Retrieve a single file by path.
91
+ * @param path - Relative file path (e.g. "expertise/retry.md").
92
+ */
93
+ retrieve(path: string): Promise<ReadResponse>;
94
+ /**
95
+ * Search all layers (vectors + BM25 + knowledge graph).
96
+ * @param query - What to search for.
97
+ * @param options.limit - Max results. Default 10, max 100.
98
+ * @param options.layer - Optional filter: "expertise", "memory", or "root".
99
+ */
100
+ search(query: string, options?: SearchOptions): Promise<SearchResponse>;
101
+ /**
102
+ * Add or update knowledge. All layers updated automatically.
103
+ * @param path - Where to write (e.g. "expertise/retry.md").
104
+ * @param content - Markdown content.
105
+ * @param layer - "expertise", "memory", or "root".
106
+ * @param topic - Category/topic for this knowledge.
107
+ * @param options.confidence - How certain (0.0-1.0). Default 0.9.
108
+ * @param options.relates_to - Related file names.
109
+ */
110
+ add(path: string, content: string, layer: "expertise" | "memory" | "root", topic: string, options?: AddOptions): Promise<WriteResponse>;
111
+ /**
112
+ * Delete knowledge from all layers (cascading).
113
+ * @param path - Relative file path to delete.
114
+ */
115
+ forget(path: string): Promise<void>;
116
+ }
117
+
118
+ /** Cogspace SDK error hierarchy. */
119
+ declare class CogspaceError extends Error {
120
+ readonly status: number | undefined;
121
+ readonly code: string | undefined;
122
+ constructor(message: string, status?: number, code?: string);
123
+ }
124
+ declare class AuthError extends CogspaceError {
125
+ constructor(message: string, status?: number);
126
+ }
127
+ declare class NotFoundError extends CogspaceError {
128
+ constructor(message: string, status?: number);
129
+ }
130
+ declare class RateLimitError extends CogspaceError {
131
+ constructor(message: string, status?: number);
132
+ }
133
+ declare class ServerError extends CogspaceError {
134
+ constructor(message: string, status?: number);
135
+ }
136
+ declare class TimeoutError extends CogspaceError {
137
+ constructor(message: string);
138
+ }
139
+ declare class LimitExceededError extends CogspaceError {
140
+ constructor(message: string);
141
+ }
142
+
143
+ /**
144
+ * Cogspace TypeScript SDK v0.2.0 — persistent knowledge layer for AI agents.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * import { Cogspace } from "@cogspace/sdk";
149
+ *
150
+ * // Reads COGSPACE_API_KEY from environment
151
+ * const cog = new Cogspace();
152
+ * const space = await cog.space("my-agent");
153
+ *
154
+ * // See what exists
155
+ * const files = await space.list("expertise");
156
+ *
157
+ * // Add knowledge
158
+ * await space.add(
159
+ * "expertise/retry.md",
160
+ * "# Retry Patterns\nUse exponential backoff...",
161
+ * "expertise",
162
+ * "retry-patterns",
163
+ * { confidence: 0.95 }
164
+ * );
165
+ *
166
+ * // Search
167
+ * const results = await space.search("retry logic", { limit: 5 });
168
+ *
169
+ * // Retrieve a file
170
+ * const file = await space.retrieve("expertise/retry.md");
171
+ *
172
+ * // Delete
173
+ * await space.forget("expertise/retry.md");
174
+ * ```
175
+ */
176
+
177
+ interface CogspaceConfig extends ClientConfig {
178
+ apiKey?: string;
179
+ baseUrl?: string;
180
+ timeout?: number;
181
+ maxRetries?: number;
182
+ }
183
+ /**
184
+ * Cogspace client. Instantiate once per process and reuse.
185
+ *
186
+ * Reads COGSPACE_API_KEY from environment automatically.
187
+ */
188
+ declare class Cogspace {
189
+ private readonly client;
190
+ private readonly spaceCache;
191
+ constructor(config?: CogspaceConfig);
192
+ private resolveSpaceId;
193
+ /** Get a space-scoped client by name or ID. */
194
+ space(nameOrId: string): Promise<SpaceClient>;
195
+ /** List all your spaces. */
196
+ listSpaces(): Promise<Space[]>;
197
+ /** Create a new space. */
198
+ createSpace(name: string): Promise<Space>;
199
+ }
200
+
201
+ export { type AddOptions, AuthError, Cogspace, type CogspaceConfig, CogspaceError, HttpClient, LimitExceededError, type ListResponse, NotFoundError, RateLimitError, type ReadResponse, type SearchItem, type SearchOptions, type SearchResponse, ServerError, type Space, SpaceClient, TimeoutError, type WriteResponse };
package/dist/index.js ADDED
@@ -0,0 +1,265 @@
1
+ // src/errors.ts
2
+ var CogspaceError = class extends Error {
3
+ constructor(message, status, code) {
4
+ super(message);
5
+ this.name = "CogspaceError";
6
+ this.status = status;
7
+ this.code = code;
8
+ }
9
+ };
10
+ var AuthError = class extends CogspaceError {
11
+ constructor(message, status) {
12
+ super(message, status);
13
+ this.name = "AuthError";
14
+ }
15
+ };
16
+ var NotFoundError = class extends CogspaceError {
17
+ constructor(message, status) {
18
+ super(message, status);
19
+ this.name = "NotFoundError";
20
+ }
21
+ };
22
+ var RateLimitError = class extends CogspaceError {
23
+ constructor(message, status) {
24
+ super(message, status);
25
+ this.name = "RateLimitError";
26
+ }
27
+ };
28
+ var ServerError = class extends CogspaceError {
29
+ constructor(message, status) {
30
+ super(message, status);
31
+ this.name = "ServerError";
32
+ }
33
+ };
34
+ var TimeoutError = class extends CogspaceError {
35
+ constructor(message) {
36
+ super(message);
37
+ this.name = "TimeoutError";
38
+ }
39
+ };
40
+ var LimitExceededError = class extends CogspaceError {
41
+ constructor(message) {
42
+ super(message);
43
+ this.name = "LimitExceededError";
44
+ }
45
+ };
46
+ function raiseForStatus(status, body) {
47
+ const message = String(body.detail ?? body.message ?? `HTTP ${status}`);
48
+ const code = body.error;
49
+ if (status === 401) throw new AuthError(message, status);
50
+ if (status === 404) throw new NotFoundError(message, status);
51
+ if (status === 429) throw new RateLimitError(message, status);
52
+ if (status >= 500) throw new ServerError(message, status);
53
+ throw new CogspaceError(message, status, code);
54
+ }
55
+
56
+ // src/client.ts
57
+ var RETRY_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
58
+ var HttpClient = class {
59
+ constructor(config = {}) {
60
+ const envKey = typeof process !== "undefined" && process.env ? process.env["COGSPACE_API_KEY"] : void 0;
61
+ const key = config.apiKey ?? envKey ?? "";
62
+ if (!key) {
63
+ throw new Error(
64
+ "API key is required. Pass apiKey: in config or set the COGSPACE_API_KEY environment variable."
65
+ );
66
+ }
67
+ this.apiKey = key;
68
+ this.baseUrl = (config.baseUrl ?? "https://platform.cogspace.ai").replace(/\/$/, "");
69
+ this.timeout = config.timeout ?? 3e4;
70
+ this.maxRetries = config.maxRetries ?? 3;
71
+ }
72
+ headers() {
73
+ return {
74
+ Authorization: `Bearer ${this.apiKey}`,
75
+ "Content-Type": "application/json",
76
+ "User-Agent": "cogspace-ts/0.2.0"
77
+ };
78
+ }
79
+ async request(method, path, body, params) {
80
+ let url = `${this.baseUrl}${path}`;
81
+ if (params && Object.keys(params).length > 0) {
82
+ url += "?" + new URLSearchParams(params).toString();
83
+ }
84
+ let lastError;
85
+ for (let attempt = 0; attempt < this.maxRetries; attempt++) {
86
+ const controller = new AbortController();
87
+ const timer = setTimeout(() => controller.abort(), this.timeout);
88
+ let response;
89
+ try {
90
+ response = await fetch(url, {
91
+ method,
92
+ headers: this.headers(),
93
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
94
+ signal: controller.signal
95
+ });
96
+ } catch (err) {
97
+ clearTimeout(timer);
98
+ if (err instanceof Error && err.name === "AbortError") {
99
+ throw new TimeoutError(`Request timed out: ${path}`);
100
+ }
101
+ throw err;
102
+ }
103
+ clearTimeout(timer);
104
+ if (!RETRY_STATUSES.has(response.status)) {
105
+ if (response.status >= 400) {
106
+ let errBody = {};
107
+ try {
108
+ errBody = await response.json();
109
+ } catch {
110
+ }
111
+ raiseForStatus(response.status, errBody);
112
+ }
113
+ if (response.status === 204 || response.headers.get("content-length") === "0") {
114
+ return void 0;
115
+ }
116
+ return response.json();
117
+ }
118
+ if (attempt < this.maxRetries - 1) {
119
+ let wait = Math.pow(2, attempt) * 1e3;
120
+ const retryAfter = response.headers.get("Retry-After");
121
+ if (retryAfter) wait = parseFloat(retryAfter) * 1e3;
122
+ await new Promise((r) => setTimeout(r, wait));
123
+ let errBody = {};
124
+ try {
125
+ errBody = await response.json();
126
+ } catch {
127
+ }
128
+ lastError = new RateLimitError(String(errBody.detail ?? `HTTP ${response.status}`), response.status);
129
+ } else {
130
+ let errBody = {};
131
+ try {
132
+ errBody = await response.json();
133
+ } catch {
134
+ }
135
+ raiseForStatus(response.status, errBody);
136
+ }
137
+ }
138
+ throw lastError ?? new RateLimitError("Max retries exceeded");
139
+ }
140
+ get(path, params) {
141
+ return this.request("GET", path, void 0, params);
142
+ }
143
+ post(path, body) {
144
+ return this.request("POST", path, body);
145
+ }
146
+ delete(path, params) {
147
+ return this.request("DELETE", path, void 0, params);
148
+ }
149
+ };
150
+
151
+ // src/space.ts
152
+ var MAX_LIMIT = 100;
153
+ var SpaceClient = class {
154
+ constructor(client, spaceId) {
155
+ this.client = client;
156
+ this.spaceId = spaceId;
157
+ }
158
+ path(endpoint) {
159
+ return `/spaces/${this.spaceId}/${endpoint}`;
160
+ }
161
+ /**
162
+ * List all files in a folder.
163
+ * @param folder - Folder to list (e.g. "expertise"). Empty = entire space.
164
+ */
165
+ list(folder = "") {
166
+ return this.client.get(this.path("list"), { folder });
167
+ }
168
+ /**
169
+ * Retrieve a single file by path.
170
+ * @param path - Relative file path (e.g. "expertise/retry.md").
171
+ */
172
+ retrieve(path) {
173
+ return this.client.get(this.path("retrieve"), { path });
174
+ }
175
+ /**
176
+ * Search all layers (vectors + BM25 + knowledge graph).
177
+ * @param query - What to search for.
178
+ * @param options.limit - Max results. Default 10, max 100.
179
+ * @param options.layer - Optional filter: "expertise", "memory", or "root".
180
+ */
181
+ async search(query, options = {}) {
182
+ const limit = options.limit ?? 10;
183
+ if (limit > MAX_LIMIT) {
184
+ throw new LimitExceededError(`limit must be <= ${MAX_LIMIT}. Got: ${limit}`);
185
+ }
186
+ return this.client.post(this.path("search"), {
187
+ query,
188
+ limit,
189
+ layer: options.layer ?? null
190
+ });
191
+ }
192
+ /**
193
+ * Add or update knowledge. All layers updated automatically.
194
+ * @param path - Where to write (e.g. "expertise/retry.md").
195
+ * @param content - Markdown content.
196
+ * @param layer - "expertise", "memory", or "root".
197
+ * @param topic - Category/topic for this knowledge.
198
+ * @param options.confidence - How certain (0.0-1.0). Default 0.9.
199
+ * @param options.relates_to - Related file names.
200
+ */
201
+ add(path, content, layer, topic, options = {}) {
202
+ return this.client.post(this.path("add"), {
203
+ path,
204
+ content,
205
+ layer,
206
+ topic,
207
+ confidence: options.confidence ?? 0.9,
208
+ relates_to: options.relates_to ?? null,
209
+ agent_id: options.agent_id ?? "default"
210
+ });
211
+ }
212
+ /**
213
+ * Delete knowledge from all layers (cascading).
214
+ * @param path - Relative file path to delete.
215
+ */
216
+ forget(path) {
217
+ return this.client.delete(this.path("forget"), { path });
218
+ }
219
+ };
220
+
221
+ // src/index.ts
222
+ var Cogspace = class {
223
+ constructor(config = {}) {
224
+ this.spaceCache = /* @__PURE__ */ new Map();
225
+ this.client = new HttpClient(config);
226
+ }
227
+ async resolveSpaceId(nameOrId) {
228
+ const cached = this.spaceCache.get(nameOrId);
229
+ if (cached) return cached;
230
+ const spaces = await this.client.get("/spaces");
231
+ for (const s of spaces) {
232
+ this.spaceCache.set(s.name, s.id);
233
+ this.spaceCache.set(s.id, s.id);
234
+ if (s.name === nameOrId || s.id === nameOrId) {
235
+ return s.id;
236
+ }
237
+ }
238
+ throw new NotFoundError(`Space not found: ${nameOrId}`);
239
+ }
240
+ /** Get a space-scoped client by name or ID. */
241
+ async space(nameOrId) {
242
+ const spaceId = await this.resolveSpaceId(nameOrId);
243
+ return new SpaceClient(this.client, spaceId);
244
+ }
245
+ /** List all your spaces. */
246
+ listSpaces() {
247
+ return this.client.get("/spaces");
248
+ }
249
+ /** Create a new space. */
250
+ createSpace(name) {
251
+ return this.client.post("/spaces", { name });
252
+ }
253
+ };
254
+ export {
255
+ AuthError,
256
+ Cogspace,
257
+ CogspaceError,
258
+ HttpClient,
259
+ LimitExceededError,
260
+ NotFoundError,
261
+ RateLimitError,
262
+ ServerError,
263
+ SpaceClient,
264
+ TimeoutError
265
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "cogspace",
3
+ "version": "0.3.1",
4
+ "description": "Official Cogspace SDK — add a knowledge layer to any AI agent",
5
+ "keywords": [
6
+ "ai",
7
+ "agents",
8
+ "knowledge",
9
+ "memory",
10
+ "rag",
11
+ "sdk",
12
+ "cogspace"
13
+ ],
14
+ "homepage": "https://cogspace.ai",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/Jack-Pision/cogspace-ai.git",
18
+ "directory": "sdk/typescript"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Cogspace",
22
+ "type": "module",
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md"
36
+ ],
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean",
42
+ "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "prepublishOnly": "npm run build && npm test"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.19.43",
49
+ "tsup": "^8.0.0",
50
+ "typescript": "^5.0.0",
51
+ "vitest": "^2.0.0"
52
+ }
53
+ }