@bike4mind/sdk 0.0.0-stage → 1.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/LICENSE ADDED
@@ -0,0 +1,130 @@
1
+ Business Source License 1.1
2
+
3
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
4
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
5
+
6
+ -----------------------------------------------------------------------------
7
+
8
+ Parameters
9
+
10
+ Licensor: Bike4Mind, Inc.
11
+
12
+ Licensed Work: Bike4Mind (this repository and the components
13
+ distributed under this License).
14
+ The Licensed Work is (c) 2026 Bike4Mind, Inc.
15
+
16
+ Additional Use Grant: You may make production use of the Licensed Work,
17
+ including building, distributing, and commercializing
18
+ your own products that incorporate or are built on the
19
+ Licensed Work, provided that you may not provide to
20
+ third parties a Bike4Mind Service. A "Bike4Mind Service"
21
+ is a commercial offering (including a managed, hosted,
22
+ or software-as-a-service offering) that allows third
23
+ parties — other than your own employees and individual
24
+ contractors — to access a substantial portion of the
25
+ functionality of the Licensed Work in a manner that
26
+ competes with a commercial offering of Bike4Mind, Inc.
27
+ For the avoidance of doubt, you may self-host and operate
28
+ the Licensed Work on your own hardware or infrastructure
29
+ for your own internal purposes (including use by your
30
+ organization's employees and individual contractors).
31
+ Such internal use — including running it for your own
32
+ sovereignty, independent of any hyperscaler or model
33
+ provider — is expressly permitted and is not a Bike4Mind
34
+ Service.
35
+
36
+ Nominative name use (an additional grant): notwithstanding
37
+ the trademark reservation in the Terms below, you may use
38
+ the name "Bike4Mind" solely to state accurately that your
39
+ product or service is built on, forked from, or derived
40
+ from the Licensed Work. This permission does not extend to
41
+ using "Bike4Mind" as the name of your own product or
42
+ service, or in any manner that implies sponsorship or
43
+ endorsement by Bike4Mind, Inc. Retaining the NOTICE file
44
+ provided with the Licensed Work is encouraged; and when you
45
+ distribute a version on or after its Change Date, retaining
46
+ it is required by the Change License (Apache-2.0, Section
47
+ 4(d)). That obligation attaches to distribution, not to
48
+ hosted use.
49
+
50
+ Change Date: Two years from the date a given version of the Licensed
51
+ Work is first made publicly available. Each version
52
+ carries its own Change Date (see Terms). Bike4Mind, Inc.
53
+ may, at its discretion, designate an earlier Change Date
54
+ for any version.
55
+
56
+ Change License: Apache License, Version 2.0
57
+
58
+ For information about alternative licensing arrangements for the Licensed Work,
59
+ please contact licensing@bike4mind.com.
60
+
61
+ -----------------------------------------------------------------------------
62
+
63
+ Notice
64
+
65
+ Business Source License 1.1
66
+
67
+ Terms
68
+
69
+ The Licensor hereby grants you the right to copy, modify, create derivative
70
+ works, redistribute, and make non-production use of the Licensed Work. The
71
+ Licensor may make an Additional Use Grant, above, permitting limited production
72
+ use.
73
+
74
+ Effective on the Change Date, or the second anniversary of the first publicly
75
+ available distribution of a specific version of the Licensed Work under this
76
+ License, whichever comes first, the Licensor hereby grants you rights under
77
+ the terms of the Change License, and the rights granted in the paragraph
78
+ above terminate.
79
+
80
+ If your use of the Licensed Work does not comply with the requirements
81
+ currently in effect as described in this License, you must purchase a
82
+ commercial license from the Licensor, its affiliated entities, or authorized
83
+ resellers, or you must refrain from using the Licensed Work.
84
+
85
+ All copies of the original and modified Licensed Work, and derivative works of
86
+ the Licensed Work, are subject to this License. This License applies separately
87
+ for each version of the Licensed Work and the Change Date may vary for each
88
+ version of the Licensed Work released by Licensor.
89
+
90
+ You must conspicuously display this License on each original or modified copy of
91
+ the Licensed Work. If you receive the Licensed Work in original or modified form
92
+ from a third party, the terms and conditions set forth in this License apply to
93
+ your use of that work.
94
+
95
+ Any use of the Licensed Work in violation of this License will automatically
96
+ terminate your rights under this License for the current and all other versions
97
+ of the Licensed Work.
98
+
99
+ This License does not grant you any right in any trademark or logo of Licensor
100
+ or its affiliates (provided that you may use a trademark or logo of Licensor as
101
+ expressly required by this License).
102
+
103
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN
104
+ "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS
105
+ OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY,
106
+ FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
107
+
108
+ MariaDB hereby grants you permission to use this License's text to license your
109
+ works, and to refer to it using the trademark "Business Source License", as long
110
+ as you comply with the Covenants of Licensor below.
111
+
112
+ Covenants of Licensor
113
+
114
+ In consideration of the right to use this License's text and the "Business Source
115
+ License" name and trademark, Licensor covenants to MariaDB, and to all other
116
+ recipients of the licensed work to be provided by Licensor:
117
+
118
+ 1. To specify as the Change License the GPL Version 2.0 or any later version, or
119
+ a license that is compatible with GPL Version 2.0 or a later version, where
120
+ "compatible" means that software provided under the Change License can be
121
+ included in a program with software provided under GPL Version 2.0 or a later
122
+ version. Licensor may specify additional Change Licenses without limitation.
123
+
124
+ 2. To either: (a) specify an additional grant of rights to use that does not
125
+ impose any additional restriction on the right granted in this License, as the
126
+ Additional Use Grant; or (b) insert the text "None".
127
+
128
+ 3. To specify a Change Date.
129
+
130
+ 4. Not to modify this License in any other way.
package/README.md CHANGED
@@ -1,3 +1,125 @@
1
- # Temporary Holding Version
1
+ # @bike4mind/sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A small, typed client for the Bike4Mind HTTP API. Its types are generated from the API's OpenAPI spec, so every operation in the spec is callable with typed path params, query, body and response, with no hand-written code per endpoint.
4
+
5
+ - Runs anywhere with a global `fetch`: Node 18+, Bun, Deno, browsers.
6
+ - One runtime dependency (`eventsource-parser`, for streaming).
7
+ - Responses are typed, not validated.
8
+
9
+ The full API reference, including scopes, rate limits and async jobs, is served by every deployment at `/api/v1/docs` (the raw spec is at `/api/v1/openapi.json`).
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ npm install @bike4mind/sdk
15
+ ```
16
+
17
+ ## Create a client
18
+
19
+ ```ts
20
+ import { createClient } from '@bike4mind/sdk';
21
+
22
+ const b4m = createClient({
23
+ baseUrl: 'https://app.example.com', // your deployment; there is no default
24
+ apiKey: process.env.B4M_API_KEY, // sent as `Authorization: Bearer b4m_live_...`
25
+ });
26
+ ```
27
+
28
+ Other options:
29
+
30
+ - `getAuthToken: () => string | undefined | Promise<...>` runs before every request, and its token wins over `apiKey`. Use it for JWTs you refresh yourself.
31
+ - `fetch` is a custom fetch for timeouts, retries, proxies or tests.
32
+ - `headers` are sent on every request.
33
+
34
+ ## Call any operation
35
+
36
+ `call(operationId, args)` takes the spec's `operationId`. `params` (path), `query` and `body` are typed per operation, and `params`/`body` are required exactly when the operation requires them.
37
+
38
+ ```ts
39
+ const me = await b4m.call('getMe');
40
+ const models = await b4m.call('listModels', { query: { limit: 20 } });
41
+ const project = await b4m.call('getProject', { params: { id: projectId } });
42
+ await b4m.call('deleteProject', { params: { id: projectId } }); // 204: resolves undefined
43
+ ```
44
+
45
+ `call` returns the parsed JSON body. A non-JSON 2xx body (for example the default binary audio from `synthesizeSpeech`) throws; use `raw`, `completions` or the `tts`/`music`/`soundEffects` helpers. For a binary or streamed body, `raw(operationId, args)` returns the 2xx `Response` itself. `operations` maps each id to its `{ method, path }`.
46
+
47
+ ## Stream a completion
48
+
49
+ ```ts
50
+ for await (const event of b4m.completions({
51
+ model: 'claude-sonnet-5-5',
52
+ messages: [{ role: 'user', content: 'Hi' }],
53
+ })) {
54
+ if (event.type === 'content') process.stdout.write(event.text);
55
+ if (event.type === 'error') throw new Error(event.message);
56
+ }
57
+ ```
58
+
59
+ The endpoint opens the stream before it validates, authenticates or rate-limits, so an invalid body, a rejected key or a rate limit arrives as a yielded `{ type: 'error' }` event, not a thrown error. Only a response that never becomes a stream (a malformed JSON body, a wrong method, a proxy error) throws `B4mApiError`. Pass `{ signal }` to cancel, or `{ url }` to stream from a different endpoint; a relative `url` is joined under `baseUrl`. An absolute `url` receives the same `Authorization` header, so pass only an origin you trust. A stream that ends without `[DONE]` and without an error event throws.
60
+
61
+ ## Chat and image jobs
62
+
63
+ Chat turns and image generations and edits are queued. Each helper returns a handle whose `poll()` waits for the job to finish:
64
+
65
+ ```ts
66
+ const turn = await b4m.chat({ message: 'Summarize my last notebook' });
67
+ const quest = await turn.poll({ timeoutMs: 120_000 });
68
+ console.log(quest.reply);
69
+
70
+ const image = await b4m.generateImage({ prompt: 'a red bicycle', model: 'gpt-image-1' });
71
+ const { images } = await image.poll();
72
+ ```
73
+
74
+ `poll` backs off from `intervalMs` (default 1000 ms) up to `maxIntervalMs` (default 5000 ms). It throws `B4mQuestError` when the job ends with `type: "error"` (`reason: 'error'`), ends `stopped` (`'stopped'`), or outlives `timeoutMs` (`'timeout'`). `error.quest` holds the last state. To resume polling a known quest id, use `pollQuest(id)`.
75
+
76
+ Other async jobs (agent executions, video generations, file uploads) are plain `call`s: start the job, then poll its `get*` operation.
77
+
78
+ ## Audio
79
+
80
+ `tts`, `music` and `soundEffects` always request `encoding: 'base64'`, so a result too large for the response comes back as the `delivery: 'url'` variant instead of a redirect. A server that predates `encoding` streams raw bytes; the SDK rebuilds the same inline shape from those bytes and the `X-B4M-Audio-*` headers.
81
+
82
+ ```ts
83
+ const result = await b4m.tts({ text: 'Hello', voice: 'alloy' });
84
+ if (result.kind === 'audio' && result.data.delivery === 'inline') {
85
+ const bytes = Buffer.from(result.data.audio, 'base64');
86
+ }
87
+ ```
88
+
89
+ `tts` also returns `{ kind: 'saved-too-large', data }` when an older server rejects oversized audio with a 413 but kept a saved copy (`data.fabFileId`). To get binary audio directly, use `raw('synthesizeSpeech', { body: { text, encoding: 'binary' } })`.
90
+
91
+ ## Errors
92
+
93
+ Any non-2xx response throws `B4mApiError`:
94
+
95
+ ```ts
96
+ import { B4mApiError } from '@bike4mind/sdk';
97
+
98
+ try {
99
+ await b4m.call('getMe');
100
+ } catch (error) {
101
+ if (error instanceof B4mApiError) {
102
+ error.status; // HTTP status
103
+ error.errorCode; // e.g. 'insufficient_credits'; branch on this, not on the message
104
+ error.requestId; // body request_id or the X-Request-ID header
105
+ error.retryAfterSeconds; // from Retry-After on a 429
106
+ error.body; // the parsed body
107
+ }
108
+ }
109
+ ```
110
+
111
+ ## Types
112
+
113
+ Generated types are exported for your own code: `paths`, `components`, `Operations`, and the shortcut `Schemas` (for example `Schemas['ErrorResponse']`). Per-operation helpers are `JsonBody<'createProject'>`, `JsonResponse<'getQuest'>`, `PathParams<...>` and `QueryParams<...>`.
114
+
115
+ These names come straight from the spec (operationIds, schema names such as `getQuestResponse200`, status codes), so they are part of this package's public API: renaming one in the spec is a breaking change for code that imports it.
116
+
117
+ ## Regenerating the types (contributors)
118
+
119
+ `src/generated/` is generated from `apps/client/public/openapi.json` and checked in. From the repo root:
120
+
121
+ ```sh
122
+ pnpm turbo:openapi:generate # regenerates the spec, then the SDK types
123
+ ```
124
+
125
+ `pnpm --filter @bike4mind/sdk generate` regenerates only the SDK types from the current spec. CI fails when either is stale.