@muhkoo/connect 0.4.0-alpha.1 → 0.6.0-alpha.11
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 +40 -10
- package/dist/browser/index.js +895 -40
- package/dist/browser/index.js.map +1 -1
- package/dist/connect.d.ts +435 -10
- package/dist/server/index.js +895 -40
- package/dist/server/index.js.map +1 -1
- package/package.json +4 -2
package/dist/connect.d.ts
CHANGED
|
@@ -1812,6 +1812,16 @@ interface AuthSuccess {
|
|
|
1812
1812
|
token: string;
|
|
1813
1813
|
username: string;
|
|
1814
1814
|
}
|
|
1815
|
+
/** A vault factor record (M1.0). Wrap/iv are base64 AES-GCM; absent for phrase. */
|
|
1816
|
+
interface VaultFactor {
|
|
1817
|
+
id: string;
|
|
1818
|
+
type: "password" | "passkey" | "phrase-marker";
|
|
1819
|
+
wrap?: string;
|
|
1820
|
+
iv?: string;
|
|
1821
|
+
params?: Record<string, unknown>;
|
|
1822
|
+
label?: string;
|
|
1823
|
+
createdAt?: number;
|
|
1824
|
+
}
|
|
1815
1825
|
interface AuthClientOptions {
|
|
1816
1826
|
/** Absolute URL of the accelerator worker (no trailing slash required). */
|
|
1817
1827
|
baseUrl: string;
|
|
@@ -1836,6 +1846,28 @@ declare class AuthClient {
|
|
|
1836
1846
|
verify(token: string): Promise<{
|
|
1837
1847
|
username: string;
|
|
1838
1848
|
}>;
|
|
1849
|
+
/** Blinded OPRF evaluation — the server-gated half of a password/recovery wrap key. */
|
|
1850
|
+
oprfEvaluate(username: string, blinded: string): Promise<{
|
|
1851
|
+
evaluated: string;
|
|
1852
|
+
}>;
|
|
1853
|
+
/** Read a factor record for `username` (returns an indistinguishable decoy if absent). */
|
|
1854
|
+
vaultRead(username: string, factorType: VaultFactor["type"]): Promise<{
|
|
1855
|
+
factor: VaultFactor | null;
|
|
1856
|
+
}>;
|
|
1857
|
+
/** Add/replace a factor (session-authed; the seed is already wrapped client-side). */
|
|
1858
|
+
vaultPutFactor(token: string, factor: VaultFactor): Promise<{
|
|
1859
|
+
ok: boolean;
|
|
1860
|
+
id: string;
|
|
1861
|
+
}>;
|
|
1862
|
+
/** List the user's factor metadata (no ciphertext). Session-authed. */
|
|
1863
|
+
vaultFactors(token: string): Promise<{
|
|
1864
|
+
factors: VaultFactor[];
|
|
1865
|
+
migrated: boolean;
|
|
1866
|
+
}>;
|
|
1867
|
+
/** Remove a factor by id (can't remove the last one). Session-authed. */
|
|
1868
|
+
vaultDeleteFactor(token: string, id: string): Promise<{
|
|
1869
|
+
deleted: boolean;
|
|
1870
|
+
}>;
|
|
1839
1871
|
private json;
|
|
1840
1872
|
private parse;
|
|
1841
1873
|
}
|
|
@@ -1882,6 +1914,23 @@ interface ZkIdentity {
|
|
|
1882
1914
|
* devices.
|
|
1883
1915
|
*/
|
|
1884
1916
|
declare function deriveIdentity(username: string, password: string): Promise<ZkIdentity>;
|
|
1917
|
+
/**
|
|
1918
|
+
* Legacy master-seed derivation: `PBKDF2(password, "muhkoo-zk-v1:"||username)`.
|
|
1919
|
+
*
|
|
1920
|
+
* This was the *only* path pre-vault, where the identity descended directly from
|
|
1921
|
+
* the password. It's kept so existing accounts still re-derive their seed (and
|
|
1922
|
+
* the vault can adopt that exact seed on migration, preserving the commitment).
|
|
1923
|
+
* New accounts use a random seed (`vault.randomSeed`) instead, so their identity
|
|
1924
|
+
* is no longer a function of the password.
|
|
1925
|
+
*/
|
|
1926
|
+
declare function deriveMasterSeedFromPassword(username: string, password: string): Promise<Uint8Array>;
|
|
1927
|
+
/**
|
|
1928
|
+
* Derive the (unchanged) ZK identity from a 32-byte **master seed**. The seed is
|
|
1929
|
+
* HKDF-expanded into secret/salt + the P-256 ECDSA & ECDH keypairs exactly as
|
|
1930
|
+
* before — so the resulting commitment is byte-identical for a given seed. The
|
|
1931
|
+
* vault wraps THIS seed under each recovery factor.
|
|
1932
|
+
*/
|
|
1933
|
+
declare function deriveIdentityFromSeed(seed: Uint8Array): Promise<ZkIdentity>;
|
|
1885
1934
|
|
|
1886
1935
|
/**
|
|
1887
1936
|
* Poseidon hash wrapper used by the ZK auth flow.
|
|
@@ -2083,6 +2132,10 @@ declare function defaultSessionStore(keyPrefix?: string): SessionStore;
|
|
|
2083
2132
|
declare class SessionState {
|
|
2084
2133
|
private session;
|
|
2085
2134
|
private _identity;
|
|
2135
|
+
/** The 32-byte master seed, in-memory only (never persisted). Held after
|
|
2136
|
+
* login/register so additional recovery factors (passkey, phrase) can be
|
|
2137
|
+
* enrolled, and a password can be changed, without re-deriving. */
|
|
2138
|
+
private _seed;
|
|
2086
2139
|
private readonly store;
|
|
2087
2140
|
constructor(store?: SessionStore);
|
|
2088
2141
|
/** True once a token-bearing session exists (regardless of identity). */
|
|
@@ -2099,6 +2152,10 @@ declare class SessionState {
|
|
|
2099
2152
|
setSession(session: StoredSession): Promise<void>;
|
|
2100
2153
|
/** Attach derived identity material to the current session. */
|
|
2101
2154
|
setIdentity(identity: ZkIdentity): void;
|
|
2155
|
+
/** The in-memory master seed (or null when locked / not held). */
|
|
2156
|
+
get seed(): Uint8Array | null;
|
|
2157
|
+
/** Hold the master seed in memory (set on login/register when available). */
|
|
2158
|
+
setSeed(seed: Uint8Array | null): void;
|
|
2102
2159
|
/** Load a persisted session (used by `restore()`); identity stays null. */
|
|
2103
2160
|
loadPersisted(): Promise<StoredSession | null>;
|
|
2104
2161
|
/** Drop all session + identity state and clear persistence. */
|
|
@@ -2122,6 +2179,17 @@ declare class SessionState {
|
|
|
2122
2179
|
* at-rest encryption and the messaging ratchet without re-deriving.
|
|
2123
2180
|
*/
|
|
2124
2181
|
|
|
2182
|
+
/**
|
|
2183
|
+
* Thrown when the identity vault can't be reached to unlock the seed — a network
|
|
2184
|
+
* failure, a 5xx, or the per-user rate limit (429). This is distinct from a wrong
|
|
2185
|
+
* password, and is surfaced so `login`/`unlock` do NOT silently fall back to the
|
|
2186
|
+
* legacy password derivation (which, for a vault account, yields a misleading
|
|
2187
|
+
* "commitment mismatch"). Callers should ask the user to retry, not re-enter a
|
|
2188
|
+
* password.
|
|
2189
|
+
*/
|
|
2190
|
+
declare class VaultUnavailableError extends Error {
|
|
2191
|
+
constructor(cause?: unknown);
|
|
2192
|
+
}
|
|
2125
2193
|
/** What the auth methods resolve to — the stable, non-secret user facts. */
|
|
2126
2194
|
interface AuthUser {
|
|
2127
2195
|
username: string;
|
|
@@ -2152,17 +2220,26 @@ declare class ZkAuth {
|
|
|
2152
2220
|
private readonly deps;
|
|
2153
2221
|
constructor(deps: ZkAuthDeps);
|
|
2154
2222
|
/**
|
|
2155
|
-
* Register a new user, then (by default) sign them in.
|
|
2156
|
-
*
|
|
2157
|
-
*
|
|
2223
|
+
* Register a new user, then (by default) sign them in.
|
|
2224
|
+
*
|
|
2225
|
+
* M1.0: the identity now descends from a **random master seed** (not the
|
|
2226
|
+
* password), so it's recoverable + the password can be changed. We register
|
|
2227
|
+
* the commitment, sign in with the in-memory identity to get a token, then
|
|
2228
|
+
* enroll the OPRF-gated **password factor** (the seed wrapped under a key the
|
|
2229
|
+
* server can't derive offline). Future logins unlock the seed via that factor.
|
|
2158
2230
|
*/
|
|
2159
2231
|
register(params: RegisterParams): Promise<AuthUser>;
|
|
2160
2232
|
/**
|
|
2161
|
-
* Sign in
|
|
2162
|
-
*
|
|
2163
|
-
*
|
|
2233
|
+
* Sign in. M1.0 is **vault-first**: read the password factor and OPRF-unwrap
|
|
2234
|
+
* the master seed → identity. If that fails (a pre-vault account, whose factor
|
|
2235
|
+
* is absent so the server returns a decoy, or a wrong password), fall back to
|
|
2236
|
+
* the legacy password-derived identity. Either way we then prove knowledge of
|
|
2237
|
+
* the identity and trade it for a session token.
|
|
2164
2238
|
*/
|
|
2165
2239
|
login(username: string, password: string, opts?: LoginOptions): Promise<AuthUser>;
|
|
2240
|
+
/** Enroll the password factor for a legacy (pre-vault) account. Idempotent +
|
|
2241
|
+
* best-effort; failure just means we retry on the next login. */
|
|
2242
|
+
private migrateLegacyPasswordFactor;
|
|
2166
2243
|
/**
|
|
2167
2244
|
* Silently re-authenticate the current user without prompting for a
|
|
2168
2245
|
* password. Only possible while the client is **unlocked** — i.e. the
|
|
@@ -2200,6 +2277,60 @@ declare class ZkAuth {
|
|
|
2200
2277
|
* the password by checking the derived commitment matches the session's.
|
|
2201
2278
|
*/
|
|
2202
2279
|
unlock(password: string): Promise<void>;
|
|
2280
|
+
/**
|
|
2281
|
+
* Generate a 24-word **recovery phrase** that encodes the master seed, and
|
|
2282
|
+
* record a marker in the vault so the UI knows one exists. Show the returned
|
|
2283
|
+
* phrase to the user ONCE — it's never stored server-side (the phrase *is* the
|
|
2284
|
+
* seed). Requires being signed in (the seed must be held in memory).
|
|
2285
|
+
*/
|
|
2286
|
+
enrollRecoveryPhrase(): Promise<string>;
|
|
2287
|
+
/**
|
|
2288
|
+
* Recover an account with its recovery phrase (the "forgot password" path).
|
|
2289
|
+
* Decodes the phrase to the master seed → identity → session. After this,
|
|
2290
|
+
* call {@link changePassword} to set a new password. No server lookup needed.
|
|
2291
|
+
*/
|
|
2292
|
+
recoverWithPhrase(username: string, mnemonic: string, opts?: LoginOptions): Promise<AuthUser>;
|
|
2293
|
+
/**
|
|
2294
|
+
* Change the password — re-wraps the (unchanged) master seed under the new
|
|
2295
|
+
* password's OPRF-gated key. The identity/commitment never moves. Requires
|
|
2296
|
+
* being signed in (or freshly recovered) so the seed is held.
|
|
2297
|
+
*/
|
|
2298
|
+
changePassword(newPassword: string): Promise<void>;
|
|
2299
|
+
/** Whether this browser can use passkeys (WebAuthn) at all. */
|
|
2300
|
+
passkeyAvailable(): boolean;
|
|
2301
|
+
/**
|
|
2302
|
+
* Whether this browser's authenticator can do the **PRF extension** our
|
|
2303
|
+
* passkey factor requires. A browser may support passkeys generally but not
|
|
2304
|
+
* PRF — in which case enrolling one would fail. Resolves `true`/`false`, or
|
|
2305
|
+
* `null` when it can't be determined (no capabilities API). Use this to gate
|
|
2306
|
+
* the passkey UI so users don't hit a dead-end error.
|
|
2307
|
+
*/
|
|
2308
|
+
passkeyPrfAvailable(): Promise<boolean | null>;
|
|
2309
|
+
/**
|
|
2310
|
+
* Add a **passkey** recovery factor. Creates a WebAuthn passkey with PRF,
|
|
2311
|
+
* wraps the master seed under its PRF output, and stores the factor. The
|
|
2312
|
+
* passkey (synced via the platform's keychain) then unlocks the account on
|
|
2313
|
+
* any device — no password. Requires being signed in (seed held in memory).
|
|
2314
|
+
*/
|
|
2315
|
+
enrollPasskey(opts?: {
|
|
2316
|
+
rpId?: string;
|
|
2317
|
+
rpName?: string;
|
|
2318
|
+
label?: string;
|
|
2319
|
+
}): Promise<void>;
|
|
2320
|
+
/**
|
|
2321
|
+
* Sign in with a passkey (no password). Reads the passkey factor, evaluates
|
|
2322
|
+
* its PRF, unwraps the master seed → identity → session.
|
|
2323
|
+
*/
|
|
2324
|
+
loginWithPasskey(username: string, opts?: LoginOptions): Promise<AuthUser>;
|
|
2325
|
+
/** List the user's enrolled login methods (metadata only). Session-authed. */
|
|
2326
|
+
listFactors(): Promise<Array<{
|
|
2327
|
+
id: string;
|
|
2328
|
+
type: string;
|
|
2329
|
+
label?: string;
|
|
2330
|
+
createdAt?: number;
|
|
2331
|
+
}>>;
|
|
2332
|
+
/** Remove a login method by id (can't remove your only one). Session-authed. */
|
|
2333
|
+
removeFactor(id: string): Promise<void>;
|
|
2203
2334
|
/** Sign out: clears the session, identity, and persisted token. */
|
|
2204
2335
|
logout(): Promise<void>;
|
|
2205
2336
|
/** The signed-in user, or `null`. Synchronous read of current state. */
|
|
@@ -2213,8 +2344,43 @@ declare class ZkAuth {
|
|
|
2213
2344
|
get identity(): ZkIdentity | null;
|
|
2214
2345
|
/** The current session token, or `null` when signed out. */
|
|
2215
2346
|
get token(): string | null;
|
|
2347
|
+
/**
|
|
2348
|
+
* The master seed as base64, or `null` when locked. The host app uses this to
|
|
2349
|
+
* wrap app-level data (e.g. chat ratchet keys) to the **seed** instead of the
|
|
2350
|
+
* password — so that data survives password changes and can be unlocked by a
|
|
2351
|
+
* passwordless (passkey) login, both of which recover the same seed.
|
|
2352
|
+
*/
|
|
2353
|
+
get seedBase64(): string | null;
|
|
2216
2354
|
/** Poseidon commitment for an identity — the value the server stores. */
|
|
2217
2355
|
private commitmentFor;
|
|
2356
|
+
/**
|
|
2357
|
+
* Derive the OPRF-gated wrap key for the password factor: `scrypt(password)`
|
|
2358
|
+
* is blinded, evaluated by the server's secret OPRF key (so it can't be
|
|
2359
|
+
* derived offline), unblinded, then HKDF'd into an AES-GCM key.
|
|
2360
|
+
*/
|
|
2361
|
+
private passwordWrapKey;
|
|
2362
|
+
/**
|
|
2363
|
+
* Try to recover the master seed from the password factor.
|
|
2364
|
+
*
|
|
2365
|
+
* Returns `null` only when the vault read SUCCEEDS but the seed can't be
|
|
2366
|
+
* unwrapped — i.e. there's no real factor (a pre-vault/legacy account, whose
|
|
2367
|
+
* read returns a decoy that won't unwrap) or the password is wrong. The caller
|
|
2368
|
+
* then legitimately falls back to the legacy password-derived identity.
|
|
2369
|
+
*
|
|
2370
|
+
* Throws {@link VaultUnavailableError} when the vault itself can't be reached
|
|
2371
|
+
* (network / 5xx / rate-limit) — so a *transient* failure is NOT silently
|
|
2372
|
+
* turned into a legacy fallback (which would surface as "commitment mismatch").
|
|
2373
|
+
*/
|
|
2374
|
+
private tryUnlockSeed;
|
|
2375
|
+
/**
|
|
2376
|
+
* Enroll/replace the password factor for `username` — wraps `seed` under the
|
|
2377
|
+
* OPRF-gated key and stores it (needs a session `token`).
|
|
2378
|
+
*
|
|
2379
|
+
* Retries: this is the step that persists the (otherwise in-memory-only)
|
|
2380
|
+
* master seed. If it fails after a fresh registration the account would be
|
|
2381
|
+
* unrecoverable, so we retry a few times before surfacing the error.
|
|
2382
|
+
*/
|
|
2383
|
+
private enrollPasswordFactor;
|
|
2218
2384
|
}
|
|
2219
2385
|
/** `client.auth` — the auth namespace. Strategies hang off here. */
|
|
2220
2386
|
declare class AuthNamespace {
|
|
@@ -2373,6 +2539,101 @@ declare class KvNamespace {
|
|
|
2373
2539
|
private getCipher;
|
|
2374
2540
|
}
|
|
2375
2541
|
|
|
2542
|
+
/**
|
|
2543
|
+
* `client.db` — the app's scalable database. A developer defines tables in the
|
|
2544
|
+
* Muhkoo portal (columns + indexes); each table is backed by its own Durable
|
|
2545
|
+
* Object SQLite instance and reachable through a sanitized REST gateway. This
|
|
2546
|
+
* namespace wraps that gateway:
|
|
2547
|
+
*
|
|
2548
|
+
* const todos = client.db.table('todos');
|
|
2549
|
+
* const { id } = await todos.insert({ title: 'Buy milk', done: false });
|
|
2550
|
+
* const one = await todos.get(id);
|
|
2551
|
+
* const { rows, nextCursor } = await todos.query({
|
|
2552
|
+
* where: [{ column: 'done', op: 'eq', value: false }],
|
|
2553
|
+
* orderBy: { column: 'rank', dir: 'asc' },
|
|
2554
|
+
* limit: 50,
|
|
2555
|
+
* });
|
|
2556
|
+
* await todos.update(id, { done: true });
|
|
2557
|
+
* await todos.delete(id);
|
|
2558
|
+
*
|
|
2559
|
+
* Authorization is the **app key** ({@link HttpClient} stamps it on every
|
|
2560
|
+
* request); the appId + environment are resolved server-side from the key, so a
|
|
2561
|
+
* key can only ever reach its own app's tables. The front end never touches the
|
|
2562
|
+
* database directly — this REST surface is the only gateway, and all input is
|
|
2563
|
+
* validated against the table's schema (parameterized statements, column +
|
|
2564
|
+
* operator allowlists). There is no raw-SQL passthrough.
|
|
2565
|
+
*
|
|
2566
|
+
* Schema is authored in the portal, not here (the SDK reads + writes rows, it
|
|
2567
|
+
* doesn't create tables). Pagination is keyset-based: pass the `nextCursor` from
|
|
2568
|
+
* a previous `query()` back as `cursor` to fetch the next page.
|
|
2569
|
+
*/
|
|
2570
|
+
|
|
2571
|
+
interface DbNamespaceDeps {
|
|
2572
|
+
http: HttpClient;
|
|
2573
|
+
}
|
|
2574
|
+
/** Comparison operators allowed in a {@link DbQuery} `where` clause. */
|
|
2575
|
+
type DbFilterOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "likeStartsWith" | "likeContains";
|
|
2576
|
+
interface DbWhereCondition {
|
|
2577
|
+
column: string;
|
|
2578
|
+
op: DbFilterOp;
|
|
2579
|
+
/** Scalar for most ops; an array for `in`; a string for the `like` family. */
|
|
2580
|
+
value: unknown;
|
|
2581
|
+
}
|
|
2582
|
+
interface DbQuery {
|
|
2583
|
+
/** Columns to return; omit for all columns. */
|
|
2584
|
+
select?: string[];
|
|
2585
|
+
/** Conditions AND-combined. */
|
|
2586
|
+
where?: DbWhereCondition[];
|
|
2587
|
+
/** Sort by a column (defaults to the primary key, ascending). */
|
|
2588
|
+
orderBy?: {
|
|
2589
|
+
column: string;
|
|
2590
|
+
dir?: "asc" | "desc";
|
|
2591
|
+
};
|
|
2592
|
+
/** Page size, clamped server-side to 100. */
|
|
2593
|
+
limit?: number;
|
|
2594
|
+
/** Opaque keyset cursor from a previous query's `nextCursor`. */
|
|
2595
|
+
cursor?: string;
|
|
2596
|
+
}
|
|
2597
|
+
interface DbQueryResult<T = Record<string, unknown>> {
|
|
2598
|
+
rows: T[];
|
|
2599
|
+
/** Cursor for the next page, or `null` when the last page was returned. */
|
|
2600
|
+
nextCursor: string | null;
|
|
2601
|
+
}
|
|
2602
|
+
/** A handle to one table — the ergonomic surface for row operations. */
|
|
2603
|
+
declare class DbTable<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
2604
|
+
private readonly http;
|
|
2605
|
+
private readonly name;
|
|
2606
|
+
constructor(http: HttpClient, name: string);
|
|
2607
|
+
private base;
|
|
2608
|
+
/** Insert a row. Returns the created row and its primary-key value. */
|
|
2609
|
+
insert(values: Partial<T>): Promise<{
|
|
2610
|
+
row: T;
|
|
2611
|
+
id: unknown;
|
|
2612
|
+
}>;
|
|
2613
|
+
/** Fetch a row by primary key, or `null` if it doesn't exist. */
|
|
2614
|
+
get(id: string | number): Promise<T | null>;
|
|
2615
|
+
/** Query rows with filters, ordering, and keyset pagination. */
|
|
2616
|
+
query(query?: DbQuery): Promise<DbQueryResult<T>>;
|
|
2617
|
+
/** Update a row by primary key. Returns the updated row. */
|
|
2618
|
+
update(id: string | number, values: Partial<T>): Promise<{
|
|
2619
|
+
row: T;
|
|
2620
|
+
}>;
|
|
2621
|
+
/** Delete a row by primary key. Returns the number of rows removed (0 or 1). */
|
|
2622
|
+
delete(id: string | number): Promise<number>;
|
|
2623
|
+
}
|
|
2624
|
+
declare class DbNamespace {
|
|
2625
|
+
private readonly deps;
|
|
2626
|
+
constructor(deps: DbNamespaceDeps);
|
|
2627
|
+
/**
|
|
2628
|
+
* A handle to a table defined in the portal. The optional type parameter
|
|
2629
|
+
* gives row operations a typed shape:
|
|
2630
|
+
*
|
|
2631
|
+
* interface Todo { _id: number; title: string; done: boolean }
|
|
2632
|
+
* const todos = client.db.table<Todo>('todos');
|
|
2633
|
+
*/
|
|
2634
|
+
table<T extends Record<string, unknown> = Record<string, unknown>>(name: string): DbTable<T>;
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2376
2637
|
/**
|
|
2377
2638
|
* `client.storage` — file storage. Hides the `FileStorage` / `ShardClient` /
|
|
2378
2639
|
* `SharedSpaceClient` primitives behind the unified client.
|
|
@@ -3228,11 +3489,41 @@ declare class SpaceNamespace {
|
|
|
3228
3489
|
* (viewers can read). Authorization rides the user session token; non-owner
|
|
3229
3490
|
* editors pass their management Space via `opts.space`.
|
|
3230
3491
|
*
|
|
3231
|
-
*
|
|
3232
|
-
* and `triggers` that decide when
|
|
3492
|
+
* An agent is "prompts + persona": a system prompt, a model, named prompt
|
|
3493
|
+
* `skills`, and `triggers` that decide when it speaks — plus optional `tools`
|
|
3494
|
+
* that let it act on the app (query/write its database, call its functions,
|
|
3495
|
+
* resolve its channels) via a server-side function-calling loop. See
|
|
3496
|
+
* {@link AgentToolsConfig}. Pair with the `@MuhkooAgent`/`@MuhkooSpace`/
|
|
3497
|
+
* `@MuhkooDB`/`@MuhkooFunction` decorators + `ejectAgentPrompt`/`ejectAgentTools`
|
|
3498
|
+
* to generate `systemPrompt` and `tools` straight from your app's surface.
|
|
3233
3499
|
*/
|
|
3234
3500
|
|
|
3235
3501
|
type AgentTriggerType = "mention" | "keyword" | "regex" | "always";
|
|
3502
|
+
/** How much database access the agent's tool-use has. */
|
|
3503
|
+
type AgentDbToolMode = "off" | "read" | "write";
|
|
3504
|
+
/**
|
|
3505
|
+
* Tool-use config — lets the agent act on the app through a function-calling
|
|
3506
|
+
* loop. Opt-in and conservatively gated server-side: a fresh agent has tools
|
|
3507
|
+
* off, the DB is read-only and per-table allowlisted, functions are per-name
|
|
3508
|
+
* allowlisted, and channels are off. **Enabling tools requires a
|
|
3509
|
+
* function-calling `model` in the same create/update payload** (the server
|
|
3510
|
+
* rejects `enabled: true` otherwise). `ejectAgentTools` produces this shape.
|
|
3511
|
+
*/
|
|
3512
|
+
interface AgentToolsConfig {
|
|
3513
|
+
enabled: boolean;
|
|
3514
|
+
db: {
|
|
3515
|
+
/** `off` = no DB tools; `read` = query/get; `write` = + insert/update/delete. */
|
|
3516
|
+
mode: AgentDbToolMode;
|
|
3517
|
+
/** Allowlisted table names the agent may touch. */
|
|
3518
|
+
tables: string[];
|
|
3519
|
+
};
|
|
3520
|
+
/** Allowlisted serverless-function names the agent may call. */
|
|
3521
|
+
functions: string[];
|
|
3522
|
+
/** Whether the agent may resolve the app's PUBLIC channels. */
|
|
3523
|
+
channels: boolean;
|
|
3524
|
+
/** Max tool-call rounds per reply (1..6). */
|
|
3525
|
+
maxIterations: number;
|
|
3526
|
+
}
|
|
3236
3527
|
interface AgentTrigger {
|
|
3237
3528
|
type: AgentTriggerType;
|
|
3238
3529
|
/** Required for `keyword` (case-insensitive substring) and `regex`. */
|
|
@@ -3258,6 +3549,8 @@ interface AgentConfig {
|
|
|
3258
3549
|
caps: {
|
|
3259
3550
|
dailyTokenBudget: number;
|
|
3260
3551
|
};
|
|
3552
|
+
/** Tool-use config (absent / `enabled: false` = prompt-only). */
|
|
3553
|
+
tools?: AgentToolsConfig;
|
|
3261
3554
|
createdAt: number;
|
|
3262
3555
|
updatedAt: number;
|
|
3263
3556
|
}
|
|
@@ -3272,6 +3565,8 @@ interface AgentCreateInput {
|
|
|
3272
3565
|
caps?: {
|
|
3273
3566
|
dailyTokenBudget: number;
|
|
3274
3567
|
};
|
|
3568
|
+
/** Grant tool-use. Requires `model` to be a function-calling model. */
|
|
3569
|
+
tools?: AgentToolsConfig;
|
|
3275
3570
|
}
|
|
3276
3571
|
type AgentUpdateInput = Partial<AgentCreateInput>;
|
|
3277
3572
|
/** Create/get response — the config plus the agent's published identity keys. */
|
|
@@ -3481,6 +3776,8 @@ declare class Client {
|
|
|
3481
3776
|
readonly auth: AuthNamespace;
|
|
3482
3777
|
/** Per-user key/value storage — `client.kv.set(...)`, etc. */
|
|
3483
3778
|
readonly kv: KvNamespace;
|
|
3779
|
+
/** App scalable database — `client.db.table('todos').query(...)`, etc. */
|
|
3780
|
+
readonly db: DbNamespace;
|
|
3484
3781
|
/** File storage — `client.storage.writeFile(...)`, etc. */
|
|
3485
3782
|
readonly storage: StorageNamespace;
|
|
3486
3783
|
/** Realtime messaging — `client.message.subscribe(...)`, etc. */
|
|
@@ -3523,6 +3820,134 @@ declare class Client {
|
|
|
3523
3820
|
recoverSession(): Promise<boolean>;
|
|
3524
3821
|
}
|
|
3525
3822
|
|
|
3823
|
+
/**
|
|
3824
|
+
* Muhkoo app decorators — declare your app's agent-facing surface in code, then
|
|
3825
|
+
* "eject" a system prompt you hand to a Programmable Agent.
|
|
3826
|
+
*
|
|
3827
|
+
* You annotate a plain class with `@MuhkooAgent` (the app's identity + how the
|
|
3828
|
+
* agent should behave) plus per-surface decorators — `@MuhkooSpace`,
|
|
3829
|
+
* `@MuhkooDB`, `@MuhkooFunction` — that describe what each channel, table, and
|
|
3830
|
+
* function is *for*. {@link ejectAgentPrompt} reads those annotations and
|
|
3831
|
+
* produces a `systemPrompt` string:
|
|
3832
|
+
*
|
|
3833
|
+
* ```ts
|
|
3834
|
+
* @MuhkooAgent({
|
|
3835
|
+
* name: "Chat Assistant",
|
|
3836
|
+
* purpose: "A helpful assistant inside a real-time team chat.",
|
|
3837
|
+
* guidance: ["Keep replies short.", "Only chime in when relevant."],
|
|
3838
|
+
* })
|
|
3839
|
+
* class ChatAssistant {
|
|
3840
|
+
* @MuhkooSpace({ description: "Main team discussion." }) general!: string;
|
|
3841
|
+
* @MuhkooDB({ access: "read", description: "Chat message history." }) messages!: unknown;
|
|
3842
|
+
* @MuhkooFunction({ description: "Open a support ticket." }) openTicket!: () => void;
|
|
3843
|
+
* }
|
|
3844
|
+
*
|
|
3845
|
+
* const systemPrompt = ejectAgentPrompt(ChatAssistant);
|
|
3846
|
+
* await client.agents.create({ handle: "assistant", displayName: "Assistant", systemPrompt });
|
|
3847
|
+
* ```
|
|
3848
|
+
*
|
|
3849
|
+
* The ejected prompt owns the **semantic** layer — what the app is, how to act,
|
|
3850
|
+
* and what each surface means. The Muhkoo runtime separately appends the
|
|
3851
|
+
* **authoritative** roster (exact columns, function parameters, and the closed
|
|
3852
|
+
* list of callable tools), so the prompt here never needs to restate schema and
|
|
3853
|
+
* can't drift from it. Decorators only describe; they never change runtime
|
|
3854
|
+
* behavior, so they're safe to apply to a throwaway descriptor class.
|
|
3855
|
+
*
|
|
3856
|
+
* Requires `experimentalDecorators` (already enabled in this package). Metadata
|
|
3857
|
+
* is captured in a per-class registry — no `reflect-metadata` dependency.
|
|
3858
|
+
*/
|
|
3859
|
+
|
|
3860
|
+
/** Whether the agent may only read a table, or read and write it. */
|
|
3861
|
+
type MuhkooDBAccess = "read" | "write";
|
|
3862
|
+
/** App-level identity + behavioral guidance — the heart of the ejected prompt. */
|
|
3863
|
+
interface MuhkooAgentMeta {
|
|
3864
|
+
/** The agent persona's name (e.g. "Chat Assistant"). */
|
|
3865
|
+
name: string;
|
|
3866
|
+
/** What the app is and the agent's role in it. One or two sentences. */
|
|
3867
|
+
purpose: string;
|
|
3868
|
+
/** Short behavioral rules, rendered as a bulleted list. */
|
|
3869
|
+
guidance?: string[];
|
|
3870
|
+
/** Optional free-form instructions appended verbatim after the surface. */
|
|
3871
|
+
instructions?: string;
|
|
3872
|
+
}
|
|
3873
|
+
/** A channel/Space the agent can resolve and post into. */
|
|
3874
|
+
interface MuhkooSpaceMeta {
|
|
3875
|
+
/** Channel name. Defaults to the decorated member's name. */
|
|
3876
|
+
name?: string;
|
|
3877
|
+
description: string;
|
|
3878
|
+
}
|
|
3879
|
+
/** An app database table the agent can query (and optionally mutate). */
|
|
3880
|
+
interface MuhkooDBMeta {
|
|
3881
|
+
/** Table name. Defaults to the decorated member's name. */
|
|
3882
|
+
table?: string;
|
|
3883
|
+
/** Read-only by default. */
|
|
3884
|
+
access?: MuhkooDBAccess;
|
|
3885
|
+
description: string;
|
|
3886
|
+
}
|
|
3887
|
+
/** A serverless function the agent can invoke via `call_function`. */
|
|
3888
|
+
interface MuhkooFunctionMeta {
|
|
3889
|
+
/** Function name. Defaults to the decorated member's name. */
|
|
3890
|
+
name?: string;
|
|
3891
|
+
description: string;
|
|
3892
|
+
}
|
|
3893
|
+
interface SpaceEntry {
|
|
3894
|
+
name: string;
|
|
3895
|
+
description: string;
|
|
3896
|
+
}
|
|
3897
|
+
interface TableEntry {
|
|
3898
|
+
table: string;
|
|
3899
|
+
access: MuhkooDBAccess;
|
|
3900
|
+
description: string;
|
|
3901
|
+
}
|
|
3902
|
+
interface FunctionEntry {
|
|
3903
|
+
name: string;
|
|
3904
|
+
description: string;
|
|
3905
|
+
}
|
|
3906
|
+
/** The full annotated surface gathered from one decorated class. */
|
|
3907
|
+
interface MuhkooAppDescriptor {
|
|
3908
|
+
agent?: MuhkooAgentMeta;
|
|
3909
|
+
spaces: SpaceEntry[];
|
|
3910
|
+
tables: TableEntry[];
|
|
3911
|
+
functions: FunctionEntry[];
|
|
3912
|
+
}
|
|
3913
|
+
/**
|
|
3914
|
+
* Class decorator. Declares the app's agent identity, purpose, and behavioral
|
|
3915
|
+
* guidance. Apply it to the class whose members carry the surface decorators.
|
|
3916
|
+
*/
|
|
3917
|
+
declare function MuhkooAgent(meta: MuhkooAgentMeta): ClassDecorator;
|
|
3918
|
+
/** Member decorator. Marks a channel/Space the agent can resolve and post to. */
|
|
3919
|
+
declare function MuhkooSpace(meta: MuhkooSpaceMeta): PropertyDecorator & MethodDecorator;
|
|
3920
|
+
/** Member decorator. Marks an app database table the agent can query/mutate. */
|
|
3921
|
+
declare function MuhkooDB(meta: MuhkooDBMeta): PropertyDecorator & MethodDecorator;
|
|
3922
|
+
/** Member decorator. Marks a serverless function the agent can call. */
|
|
3923
|
+
declare function MuhkooFunction(meta: MuhkooFunctionMeta): PropertyDecorator & MethodDecorator;
|
|
3924
|
+
/** Read back the raw descriptor a class accumulated (for tooling/tests). */
|
|
3925
|
+
declare function getMuhkooAppDescriptor(appClass: Function): MuhkooAppDescriptor | undefined;
|
|
3926
|
+
/**
|
|
3927
|
+
* Compose the agent system prompt from a `@MuhkooAgent`-decorated class. Throws
|
|
3928
|
+
* if the class isn't decorated. The result is the semantic layer only — the
|
|
3929
|
+
* runtime appends exact schema + the closed tool list at invocation time.
|
|
3930
|
+
*/
|
|
3931
|
+
declare function ejectAgentPrompt(appClass: Function): string;
|
|
3932
|
+
/**
|
|
3933
|
+
* The tools-config shape the Muhkoo platform uses to gate an agent. Alias of
|
|
3934
|
+
* `client.agents`' {@link AgentToolsConfig} so {@link ejectAgentTools} output
|
|
3935
|
+
* drops straight into `client.agents.create({ tools })`.
|
|
3936
|
+
*/
|
|
3937
|
+
type MuhkooAgentToolsConfig = AgentToolsConfig;
|
|
3938
|
+
/**
|
|
3939
|
+
* Derive a suggested tools allowlist from a decorated class — the db tables
|
|
3940
|
+
* (and whether any are writable), the callable functions, and whether channels
|
|
3941
|
+
* are in play. Pair with {@link ejectAgentPrompt} when configuring the agent.
|
|
3942
|
+
*
|
|
3943
|
+
* If any tables/functions are present the result has `enabled: true`; to
|
|
3944
|
+
* actually grant tools you must also pass a function-calling `model` in the same
|
|
3945
|
+
* `client.agents.create`/`update` call (the server enforces this).
|
|
3946
|
+
*/
|
|
3947
|
+
declare function ejectAgentTools(appClass: Function, opts?: {
|
|
3948
|
+
maxIterations?: number;
|
|
3949
|
+
}): AgentToolsConfig;
|
|
3950
|
+
|
|
3526
3951
|
/**
|
|
3527
3952
|
* KeyringClient — HTTP implementation of {@link KeyringTransport} against the
|
|
3528
3953
|
* accelerator's per-space keyring endpoints. All blobs are opaque to the
|
|
@@ -3583,5 +4008,5 @@ declare class KeyringClient implements KeyringTransport {
|
|
|
3583
4008
|
fetchMetadata(): Promise<SpaceMetadata | null>;
|
|
3584
4009
|
}
|
|
3585
4010
|
|
|
3586
|
-
export { AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AgentsNamespace, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, DEFAULT_BASE_URL, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HashKnowledge, HttpClient, HttpError, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvNamespace, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, ReedSolomonCodec, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, WSTransport, ZkAuth, buildCommitment, compilePrograms, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, generateAuthProof, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, manifestToStat, poseidonHash, quickVerify, randomBytes, shardHash, signMessage, toField, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
|
|
3587
|
-
export type { ACL, ACLEntry, AgentConfig, AgentCreateInput, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, DehydratedKeypair, DehydratedKeys, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EphemeralEvent, EpochKeyProvider, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvNamespaceDeps, LoginOptions, MessageBody, MessageDeletedEvent, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOptions, MessageSubscription, MuhkooMessageEvent, OAuthProvider, PacketCipher, PacketHeaders, PacketOptions, Participant, Permission, PermissionCheckRequest, PermissionCheckResult, PersonalSpaceClientOptions, PublicKeyJWK, RatchetState, ReceiveResult, RegisterParams, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, SealedHeaders, Session, SessionOptions, SessionStore, SetOptions, ShardClientOptions, SharedSpaceClientOptions, SnarkProof, SpaceChannelLike, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, StorageChangeEvent, StoredSession, Subscription, UserIdentity, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
|
|
4011
|
+
export { AES_GCM_IV_BYTES, AES_GCM_KEY_BYTES, AES_GCM_TAG_BYTES, AgentsNamespace, AuthClient, AuthNamespace, AuthPublicInput, Authenticator, BroadcastChannel, BroadcastChannelEvents, ChannelExistsError, ChannelNotFoundError, ChunkCipher, Client, DEFAULT_BASE_URL, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HashKnowledge, HttpClient, HttpError, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvNamespace, LocalStorageSessionStore, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, ReedSolomonCodec, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, VaultUnavailableError, WSTransport, ZkAuth, buildCommitment, compilePrograms, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deriveIdentityFromSeed, deriveMasterSeedFromPassword, ejectAgentPrompt, ejectAgentTools, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, generateAuthProof, getMuhkooAppDescriptor, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, manifestToStat, poseidonHash, quickVerify, randomBytes, shardHash, signMessage, toField, unwrapWithPassphrase, verify, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
|
|
4012
|
+
export type { ACL, ACLEntry, AgentConfig, AgentCreateInput, AgentDbToolMode, AgentProvisioned, AgentScopeOpts, AgentSkill, AgentToolsConfig, AgentTrigger, AgentTriggerType, AgentUpdateInput, AgentsNamespaceDeps, AuthClientOptions, AuthKeyPair, AuthSuccess, AuthToken, AuthType, AuthUser, Bn128WasmInstance, BroadcastChannelEvent, BroadcastChannelOptions, ChannelLike, ChunkKeyMaterial, ChunkManifest, CipherFrame, CipherMessage, CipherMessageHeader, CircuitBufferConfig, CircuitUrls, ClientOptions, DehydratedKeypair, DehydratedKeys, DoubleRatchetCipherDeps, ECDHCurve, EncodeResult, EphemeralEvent, EpochKeyProvider, FileManifest, FileNamespaceDeps, FileStat, FileStorageOptions, FunctionCaps, FunctionConfig, FunctionDeployInput, FunctionScopeOpts, FunctionTrigger, FunctionTriggerType, FunctionTriggers, FunctionUpdateInput, FunctionsNamespaceDeps, Groth16Proof, HttpClientOptions, IncomingFrame, KeyExchangeFrame, KeyPair, Keypair, KeyringClientDeps, KeyringTransport, KvNamespaceDeps, LoginOptions, MessageBody, MessageDeletedEvent, MessageEvent, MessageHeaders, MessageNamespaceDeps, MessageOptions, MessageSubscription, MuhkooAgentMeta, MuhkooAgentToolsConfig, MuhkooAppDescriptor, MuhkooDBAccess, MuhkooDBMeta, MuhkooFunctionMeta, MuhkooMessageEvent, MuhkooSpaceMeta, OAuthProvider, PacketCipher, PacketHeaders, PacketOptions, Participant, Permission, PermissionCheckRequest, PermissionCheckResult, PersonalSpaceClientOptions, PublicKeyJWK, RatchetState, ReceiveResult, RegisterParams, Role, SpaceDeps as RoomDeps, SpaceFileMetadata as RoomFileMetadata, SealedHeaders, Session, SessionOptions, SessionStore, SetOptions, ShardClientOptions, SharedSpaceClientOptions, SnarkProof, SpaceChannelLike, SpaceDeps, SpaceFileMetadata, SpaceKeyCache, SpaceKeyringDeps, SpaceMessageEvent, SpaceNamespaceDeps, StorageChangeEvent, StoredSession, Subscription, UserIdentity, VaultFactor, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
|