@muhkoo/connect 0.4.0-alpha.1 → 0.6.0-alpha.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/dist/connect.d.ts CHANGED
@@ -2373,6 +2373,101 @@ declare class KvNamespace {
2373
2373
  private getCipher;
2374
2374
  }
2375
2375
 
2376
+ /**
2377
+ * `client.db` — the app's scalable database. A developer defines tables in the
2378
+ * Muhkoo portal (columns + indexes); each table is backed by its own Durable
2379
+ * Object SQLite instance and reachable through a sanitized REST gateway. This
2380
+ * namespace wraps that gateway:
2381
+ *
2382
+ * const todos = client.db.table('todos');
2383
+ * const { id } = await todos.insert({ title: 'Buy milk', done: false });
2384
+ * const one = await todos.get(id);
2385
+ * const { rows, nextCursor } = await todos.query({
2386
+ * where: [{ column: 'done', op: 'eq', value: false }],
2387
+ * orderBy: { column: 'rank', dir: 'asc' },
2388
+ * limit: 50,
2389
+ * });
2390
+ * await todos.update(id, { done: true });
2391
+ * await todos.delete(id);
2392
+ *
2393
+ * Authorization is the **app key** ({@link HttpClient} stamps it on every
2394
+ * request); the appId + environment are resolved server-side from the key, so a
2395
+ * key can only ever reach its own app's tables. The front end never touches the
2396
+ * database directly — this REST surface is the only gateway, and all input is
2397
+ * validated against the table's schema (parameterized statements, column +
2398
+ * operator allowlists). There is no raw-SQL passthrough.
2399
+ *
2400
+ * Schema is authored in the portal, not here (the SDK reads + writes rows, it
2401
+ * doesn't create tables). Pagination is keyset-based: pass the `nextCursor` from
2402
+ * a previous `query()` back as `cursor` to fetch the next page.
2403
+ */
2404
+
2405
+ interface DbNamespaceDeps {
2406
+ http: HttpClient;
2407
+ }
2408
+ /** Comparison operators allowed in a {@link DbQuery} `where` clause. */
2409
+ type DbFilterOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "likeStartsWith" | "likeContains";
2410
+ interface DbWhereCondition {
2411
+ column: string;
2412
+ op: DbFilterOp;
2413
+ /** Scalar for most ops; an array for `in`; a string for the `like` family. */
2414
+ value: unknown;
2415
+ }
2416
+ interface DbQuery {
2417
+ /** Columns to return; omit for all columns. */
2418
+ select?: string[];
2419
+ /** Conditions AND-combined. */
2420
+ where?: DbWhereCondition[];
2421
+ /** Sort by a column (defaults to the primary key, ascending). */
2422
+ orderBy?: {
2423
+ column: string;
2424
+ dir?: "asc" | "desc";
2425
+ };
2426
+ /** Page size, clamped server-side to 100. */
2427
+ limit?: number;
2428
+ /** Opaque keyset cursor from a previous query's `nextCursor`. */
2429
+ cursor?: string;
2430
+ }
2431
+ interface DbQueryResult<T = Record<string, unknown>> {
2432
+ rows: T[];
2433
+ /** Cursor for the next page, or `null` when the last page was returned. */
2434
+ nextCursor: string | null;
2435
+ }
2436
+ /** A handle to one table — the ergonomic surface for row operations. */
2437
+ declare class DbTable<T extends Record<string, unknown> = Record<string, unknown>> {
2438
+ private readonly http;
2439
+ private readonly name;
2440
+ constructor(http: HttpClient, name: string);
2441
+ private base;
2442
+ /** Insert a row. Returns the created row and its primary-key value. */
2443
+ insert(values: Partial<T>): Promise<{
2444
+ row: T;
2445
+ id: unknown;
2446
+ }>;
2447
+ /** Fetch a row by primary key, or `null` if it doesn't exist. */
2448
+ get(id: string | number): Promise<T | null>;
2449
+ /** Query rows with filters, ordering, and keyset pagination. */
2450
+ query(query?: DbQuery): Promise<DbQueryResult<T>>;
2451
+ /** Update a row by primary key. Returns the updated row. */
2452
+ update(id: string | number, values: Partial<T>): Promise<{
2453
+ row: T;
2454
+ }>;
2455
+ /** Delete a row by primary key. Returns the number of rows removed (0 or 1). */
2456
+ delete(id: string | number): Promise<number>;
2457
+ }
2458
+ declare class DbNamespace {
2459
+ private readonly deps;
2460
+ constructor(deps: DbNamespaceDeps);
2461
+ /**
2462
+ * A handle to a table defined in the portal. The optional type parameter
2463
+ * gives row operations a typed shape:
2464
+ *
2465
+ * interface Todo { _id: number; title: string; done: boolean }
2466
+ * const todos = client.db.table<Todo>('todos');
2467
+ */
2468
+ table<T extends Record<string, unknown> = Record<string, unknown>>(name: string): DbTable<T>;
2469
+ }
2470
+
2376
2471
  /**
2377
2472
  * `client.storage` — file storage. Hides the `FileStorage` / `ShardClient` /
2378
2473
  * `SharedSpaceClient` primitives behind the unified client.
@@ -3228,11 +3323,41 @@ declare class SpaceNamespace {
3228
3323
  * (viewers can read). Authorization rides the user session token; non-owner
3229
3324
  * editors pass their management Space via `opts.space`.
3230
3325
  *
3231
- * v1 is "prompts + persona": a system prompt, a model, named prompt `skills`,
3232
- * and `triggers` that decide when the agent speaks. No tools, no code.
3326
+ * An agent is "prompts + persona": a system prompt, a model, named prompt
3327
+ * `skills`, and `triggers` that decide when it speaks — plus optional `tools`
3328
+ * that let it act on the app (query/write its database, call its functions,
3329
+ * resolve its channels) via a server-side function-calling loop. See
3330
+ * {@link AgentToolsConfig}. Pair with the `@MuhkooAgent`/`@MuhkooSpace`/
3331
+ * `@MuhkooDB`/`@MuhkooFunction` decorators + `ejectAgentPrompt`/`ejectAgentTools`
3332
+ * to generate `systemPrompt` and `tools` straight from your app's surface.
3233
3333
  */
3234
3334
 
3235
3335
  type AgentTriggerType = "mention" | "keyword" | "regex" | "always";
3336
+ /** How much database access the agent's tool-use has. */
3337
+ type AgentDbToolMode = "off" | "read" | "write";
3338
+ /**
3339
+ * Tool-use config — lets the agent act on the app through a function-calling
3340
+ * loop. Opt-in and conservatively gated server-side: a fresh agent has tools
3341
+ * off, the DB is read-only and per-table allowlisted, functions are per-name
3342
+ * allowlisted, and channels are off. **Enabling tools requires a
3343
+ * function-calling `model` in the same create/update payload** (the server
3344
+ * rejects `enabled: true` otherwise). `ejectAgentTools` produces this shape.
3345
+ */
3346
+ interface AgentToolsConfig {
3347
+ enabled: boolean;
3348
+ db: {
3349
+ /** `off` = no DB tools; `read` = query/get; `write` = + insert/update/delete. */
3350
+ mode: AgentDbToolMode;
3351
+ /** Allowlisted table names the agent may touch. */
3352
+ tables: string[];
3353
+ };
3354
+ /** Allowlisted serverless-function names the agent may call. */
3355
+ functions: string[];
3356
+ /** Whether the agent may resolve the app's PUBLIC channels. */
3357
+ channels: boolean;
3358
+ /** Max tool-call rounds per reply (1..6). */
3359
+ maxIterations: number;
3360
+ }
3236
3361
  interface AgentTrigger {
3237
3362
  type: AgentTriggerType;
3238
3363
  /** Required for `keyword` (case-insensitive substring) and `regex`. */
@@ -3258,6 +3383,8 @@ interface AgentConfig {
3258
3383
  caps: {
3259
3384
  dailyTokenBudget: number;
3260
3385
  };
3386
+ /** Tool-use config (absent / `enabled: false` = prompt-only). */
3387
+ tools?: AgentToolsConfig;
3261
3388
  createdAt: number;
3262
3389
  updatedAt: number;
3263
3390
  }
@@ -3272,6 +3399,8 @@ interface AgentCreateInput {
3272
3399
  caps?: {
3273
3400
  dailyTokenBudget: number;
3274
3401
  };
3402
+ /** Grant tool-use. Requires `model` to be a function-calling model. */
3403
+ tools?: AgentToolsConfig;
3275
3404
  }
3276
3405
  type AgentUpdateInput = Partial<AgentCreateInput>;
3277
3406
  /** Create/get response — the config plus the agent's published identity keys. */
@@ -3481,6 +3610,8 @@ declare class Client {
3481
3610
  readonly auth: AuthNamespace;
3482
3611
  /** Per-user key/value storage — `client.kv.set(...)`, etc. */
3483
3612
  readonly kv: KvNamespace;
3613
+ /** App scalable database — `client.db.table('todos').query(...)`, etc. */
3614
+ readonly db: DbNamespace;
3484
3615
  /** File storage — `client.storage.writeFile(...)`, etc. */
3485
3616
  readonly storage: StorageNamespace;
3486
3617
  /** Realtime messaging — `client.message.subscribe(...)`, etc. */
@@ -3523,6 +3654,134 @@ declare class Client {
3523
3654
  recoverSession(): Promise<boolean>;
3524
3655
  }
3525
3656
 
3657
+ /**
3658
+ * Muhkoo app decorators — declare your app's agent-facing surface in code, then
3659
+ * "eject" a system prompt you hand to a Programmable Agent.
3660
+ *
3661
+ * You annotate a plain class with `@MuhkooAgent` (the app's identity + how the
3662
+ * agent should behave) plus per-surface decorators — `@MuhkooSpace`,
3663
+ * `@MuhkooDB`, `@MuhkooFunction` — that describe what each channel, table, and
3664
+ * function is *for*. {@link ejectAgentPrompt} reads those annotations and
3665
+ * produces a `systemPrompt` string:
3666
+ *
3667
+ * ```ts
3668
+ * @MuhkooAgent({
3669
+ * name: "Chat Assistant",
3670
+ * purpose: "A helpful assistant inside a real-time team chat.",
3671
+ * guidance: ["Keep replies short.", "Only chime in when relevant."],
3672
+ * })
3673
+ * class ChatAssistant {
3674
+ * @MuhkooSpace({ description: "Main team discussion." }) general!: string;
3675
+ * @MuhkooDB({ access: "read", description: "Chat message history." }) messages!: unknown;
3676
+ * @MuhkooFunction({ description: "Open a support ticket." }) openTicket!: () => void;
3677
+ * }
3678
+ *
3679
+ * const systemPrompt = ejectAgentPrompt(ChatAssistant);
3680
+ * await client.agents.create({ handle: "assistant", displayName: "Assistant", systemPrompt });
3681
+ * ```
3682
+ *
3683
+ * The ejected prompt owns the **semantic** layer — what the app is, how to act,
3684
+ * and what each surface means. The Muhkoo runtime separately appends the
3685
+ * **authoritative** roster (exact columns, function parameters, and the closed
3686
+ * list of callable tools), so the prompt here never needs to restate schema and
3687
+ * can't drift from it. Decorators only describe; they never change runtime
3688
+ * behavior, so they're safe to apply to a throwaway descriptor class.
3689
+ *
3690
+ * Requires `experimentalDecorators` (already enabled in this package). Metadata
3691
+ * is captured in a per-class registry — no `reflect-metadata` dependency.
3692
+ */
3693
+
3694
+ /** Whether the agent may only read a table, or read and write it. */
3695
+ type MuhkooDBAccess = "read" | "write";
3696
+ /** App-level identity + behavioral guidance — the heart of the ejected prompt. */
3697
+ interface MuhkooAgentMeta {
3698
+ /** The agent persona's name (e.g. "Chat Assistant"). */
3699
+ name: string;
3700
+ /** What the app is and the agent's role in it. One or two sentences. */
3701
+ purpose: string;
3702
+ /** Short behavioral rules, rendered as a bulleted list. */
3703
+ guidance?: string[];
3704
+ /** Optional free-form instructions appended verbatim after the surface. */
3705
+ instructions?: string;
3706
+ }
3707
+ /** A channel/Space the agent can resolve and post into. */
3708
+ interface MuhkooSpaceMeta {
3709
+ /** Channel name. Defaults to the decorated member's name. */
3710
+ name?: string;
3711
+ description: string;
3712
+ }
3713
+ /** An app database table the agent can query (and optionally mutate). */
3714
+ interface MuhkooDBMeta {
3715
+ /** Table name. Defaults to the decorated member's name. */
3716
+ table?: string;
3717
+ /** Read-only by default. */
3718
+ access?: MuhkooDBAccess;
3719
+ description: string;
3720
+ }
3721
+ /** A serverless function the agent can invoke via `call_function`. */
3722
+ interface MuhkooFunctionMeta {
3723
+ /** Function name. Defaults to the decorated member's name. */
3724
+ name?: string;
3725
+ description: string;
3726
+ }
3727
+ interface SpaceEntry {
3728
+ name: string;
3729
+ description: string;
3730
+ }
3731
+ interface TableEntry {
3732
+ table: string;
3733
+ access: MuhkooDBAccess;
3734
+ description: string;
3735
+ }
3736
+ interface FunctionEntry {
3737
+ name: string;
3738
+ description: string;
3739
+ }
3740
+ /** The full annotated surface gathered from one decorated class. */
3741
+ interface MuhkooAppDescriptor {
3742
+ agent?: MuhkooAgentMeta;
3743
+ spaces: SpaceEntry[];
3744
+ tables: TableEntry[];
3745
+ functions: FunctionEntry[];
3746
+ }
3747
+ /**
3748
+ * Class decorator. Declares the app's agent identity, purpose, and behavioral
3749
+ * guidance. Apply it to the class whose members carry the surface decorators.
3750
+ */
3751
+ declare function MuhkooAgent(meta: MuhkooAgentMeta): ClassDecorator;
3752
+ /** Member decorator. Marks a channel/Space the agent can resolve and post to. */
3753
+ declare function MuhkooSpace(meta: MuhkooSpaceMeta): PropertyDecorator & MethodDecorator;
3754
+ /** Member decorator. Marks an app database table the agent can query/mutate. */
3755
+ declare function MuhkooDB(meta: MuhkooDBMeta): PropertyDecorator & MethodDecorator;
3756
+ /** Member decorator. Marks a serverless function the agent can call. */
3757
+ declare function MuhkooFunction(meta: MuhkooFunctionMeta): PropertyDecorator & MethodDecorator;
3758
+ /** Read back the raw descriptor a class accumulated (for tooling/tests). */
3759
+ declare function getMuhkooAppDescriptor(appClass: Function): MuhkooAppDescriptor | undefined;
3760
+ /**
3761
+ * Compose the agent system prompt from a `@MuhkooAgent`-decorated class. Throws
3762
+ * if the class isn't decorated. The result is the semantic layer only — the
3763
+ * runtime appends exact schema + the closed tool list at invocation time.
3764
+ */
3765
+ declare function ejectAgentPrompt(appClass: Function): string;
3766
+ /**
3767
+ * The tools-config shape the Muhkoo platform uses to gate an agent. Alias of
3768
+ * `client.agents`' {@link AgentToolsConfig} so {@link ejectAgentTools} output
3769
+ * drops straight into `client.agents.create({ tools })`.
3770
+ */
3771
+ type MuhkooAgentToolsConfig = AgentToolsConfig;
3772
+ /**
3773
+ * Derive a suggested tools allowlist from a decorated class — the db tables
3774
+ * (and whether any are writable), the callable functions, and whether channels
3775
+ * are in play. Pair with {@link ejectAgentPrompt} when configuring the agent.
3776
+ *
3777
+ * If any tables/functions are present the result has `enabled: true`; to
3778
+ * actually grant tools you must also pass a function-calling `model` in the same
3779
+ * `client.agents.create`/`update` call (the server enforces this).
3780
+ */
3781
+ declare function ejectAgentTools(appClass: Function, opts?: {
3782
+ maxIterations?: number;
3783
+ }): AgentToolsConfig;
3784
+
3526
3785
  /**
3527
3786
  * KeyringClient — HTTP implementation of {@link KeyringTransport} against the
3528
3787
  * accelerator's per-space keyring endpoints. All blobs are opaque to the
@@ -3583,5 +3842,5 @@ declare class KeyringClient implements KeyringTransport {
3583
3842
  fetchMetadata(): Promise<SpaceMetadata | null>;
3584
3843
  }
3585
3844
 
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 };
3845
+ 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, WSTransport, ZkAuth, buildCommitment, compilePrograms, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, 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 };
3846
+ 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, VerificationKey, WSMessage, WSMessageType, WSTransportOptions, WrappedPayload, WriteFileInput, WriteFileOptions, WriteToShardsInput, ZkAuthDeps, ZkAuthenticateRequest, ZkChallengeResponse, ZkCompiled, ZkIdentity, ZkRegisterRequest, ZkRegisterResponse };
@@ -3674,6 +3674,92 @@ class KvNamespace {
3674
3674
  }
3675
3675
  }
3676
3676
 
3677
+ /**
3678
+ * `client.db` — the app's scalable database. A developer defines tables in the
3679
+ * Muhkoo portal (columns + indexes); each table is backed by its own Durable
3680
+ * Object SQLite instance and reachable through a sanitized REST gateway. This
3681
+ * namespace wraps that gateway:
3682
+ *
3683
+ * const todos = client.db.table('todos');
3684
+ * const { id } = await todos.insert({ title: 'Buy milk', done: false });
3685
+ * const one = await todos.get(id);
3686
+ * const { rows, nextCursor } = await todos.query({
3687
+ * where: [{ column: 'done', op: 'eq', value: false }],
3688
+ * orderBy: { column: 'rank', dir: 'asc' },
3689
+ * limit: 50,
3690
+ * });
3691
+ * await todos.update(id, { done: true });
3692
+ * await todos.delete(id);
3693
+ *
3694
+ * Authorization is the **app key** ({@link HttpClient} stamps it on every
3695
+ * request); the appId + environment are resolved server-side from the key, so a
3696
+ * key can only ever reach its own app's tables. The front end never touches the
3697
+ * database directly — this REST surface is the only gateway, and all input is
3698
+ * validated against the table's schema (parameterized statements, column +
3699
+ * operator allowlists). There is no raw-SQL passthrough.
3700
+ *
3701
+ * Schema is authored in the portal, not here (the SDK reads + writes rows, it
3702
+ * doesn't create tables). Pagination is keyset-based: pass the `nextCursor` from
3703
+ * a previous `query()` back as `cursor` to fetch the next page.
3704
+ */
3705
+ /** A handle to one table — the ergonomic surface for row operations. */
3706
+ class DbTable {
3707
+ http;
3708
+ name;
3709
+ constructor(http, name) {
3710
+ this.http = http;
3711
+ this.name = name;
3712
+ }
3713
+ base() {
3714
+ return `/api/db/${encodeURIComponent(this.name)}`;
3715
+ }
3716
+ /** Insert a row. Returns the created row and its primary-key value. */
3717
+ async insert(values) {
3718
+ return this.http.post(this.base(), { values });
3719
+ }
3720
+ /** Fetch a row by primary key, or `null` if it doesn't exist. */
3721
+ async get(id) {
3722
+ try {
3723
+ const res = await this.http.get(`${this.base()}/${encodeURIComponent(String(id))}`);
3724
+ return res.row;
3725
+ }
3726
+ catch (e) {
3727
+ if (e?.status === 404)
3728
+ return null;
3729
+ throw e;
3730
+ }
3731
+ }
3732
+ /** Query rows with filters, ordering, and keyset pagination. */
3733
+ async query(query = {}) {
3734
+ return this.http.post(`${this.base()}/query`, query);
3735
+ }
3736
+ /** Update a row by primary key. Returns the updated row. */
3737
+ async update(id, values) {
3738
+ return this.http.patch(`${this.base()}/${encodeURIComponent(String(id))}`, { values });
3739
+ }
3740
+ /** Delete a row by primary key. Returns the number of rows removed (0 or 1). */
3741
+ async delete(id) {
3742
+ const res = await this.http.del(`${this.base()}/${encodeURIComponent(String(id))}`);
3743
+ return res.deleted ?? 0;
3744
+ }
3745
+ }
3746
+ class DbNamespace {
3747
+ deps;
3748
+ constructor(deps) {
3749
+ this.deps = deps;
3750
+ }
3751
+ /**
3752
+ * A handle to a table defined in the portal. The optional type parameter
3753
+ * gives row operations a typed shape:
3754
+ *
3755
+ * interface Todo { _id: number; title: string; done: boolean }
3756
+ * const todos = client.db.table<Todo>('todos');
3757
+ */
3758
+ table(name) {
3759
+ return new DbTable(this.deps.http, name);
3760
+ }
3761
+ }
3762
+
3677
3763
  /**
3678
3764
  * Wire types for the storage layer.
3679
3765
  *
@@ -6596,8 +6682,13 @@ class SpaceNamespace {
6596
6682
  * (viewers can read). Authorization rides the user session token; non-owner
6597
6683
  * editors pass their management Space via `opts.space`.
6598
6684
  *
6599
- * v1 is "prompts + persona": a system prompt, a model, named prompt `skills`,
6600
- * and `triggers` that decide when the agent speaks. No tools, no code.
6685
+ * An agent is "prompts + persona": a system prompt, a model, named prompt
6686
+ * `skills`, and `triggers` that decide when it speaks — plus optional `tools`
6687
+ * that let it act on the app (query/write its database, call its functions,
6688
+ * resolve its channels) via a server-side function-calling loop. See
6689
+ * {@link AgentToolsConfig}. Pair with the `@MuhkooAgent`/`@MuhkooSpace`/
6690
+ * `@MuhkooDB`/`@MuhkooFunction` decorators + `ejectAgentPrompt`/`ejectAgentTools`
6691
+ * to generate `systemPrompt` and `tools` straight from your app's surface.
6601
6692
  */
6602
6693
  class AgentsNamespace {
6603
6694
  deps;
@@ -6745,6 +6836,8 @@ class Client {
6745
6836
  auth;
6746
6837
  /** Per-user key/value storage — `client.kv.set(...)`, etc. */
6747
6838
  kv;
6839
+ /** App scalable database — `client.db.table('todos').query(...)`, etc. */
6840
+ db;
6748
6841
  /** File storage — `client.storage.writeFile(...)`, etc. */
6749
6842
  storage;
6750
6843
  /** Realtime messaging — `client.message.subscribe(...)`, etc. */
@@ -6782,6 +6875,7 @@ class Client {
6782
6875
  const wsBaseUrl = toWsBase(this.baseUrl);
6783
6876
  this.auth = new AuthNamespace({ auth: authClient, circuits, session: this.session });
6784
6877
  this.kv = new KvNamespace({ http: this.http, session: this.session, wsBaseUrl });
6878
+ this.db = new DbNamespace({ http: this.http });
6785
6879
  this.storage = new StorageNamespace({ http: this.http, baseUrl: this.baseUrl, kv: this.kv });
6786
6880
  this.message = new MessageNamespace({ http: this.http, session: this.session, wsBaseUrl });
6787
6881
  // Group keys are cached in the user's PersonalSpace (encrypted at rest
@@ -6852,6 +6946,177 @@ class Client {
6852
6946
  }
6853
6947
  }
6854
6948
 
6949
+ /**
6950
+ * Muhkoo app decorators — declare your app's agent-facing surface in code, then
6951
+ * "eject" a system prompt you hand to a Programmable Agent.
6952
+ *
6953
+ * You annotate a plain class with `@MuhkooAgent` (the app's identity + how the
6954
+ * agent should behave) plus per-surface decorators — `@MuhkooSpace`,
6955
+ * `@MuhkooDB`, `@MuhkooFunction` — that describe what each channel, table, and
6956
+ * function is *for*. {@link ejectAgentPrompt} reads those annotations and
6957
+ * produces a `systemPrompt` string:
6958
+ *
6959
+ * ```ts
6960
+ * @MuhkooAgent({
6961
+ * name: "Chat Assistant",
6962
+ * purpose: "A helpful assistant inside a real-time team chat.",
6963
+ * guidance: ["Keep replies short.", "Only chime in when relevant."],
6964
+ * })
6965
+ * class ChatAssistant {
6966
+ * @MuhkooSpace({ description: "Main team discussion." }) general!: string;
6967
+ * @MuhkooDB({ access: "read", description: "Chat message history." }) messages!: unknown;
6968
+ * @MuhkooFunction({ description: "Open a support ticket." }) openTicket!: () => void;
6969
+ * }
6970
+ *
6971
+ * const systemPrompt = ejectAgentPrompt(ChatAssistant);
6972
+ * await client.agents.create({ handle: "assistant", displayName: "Assistant", systemPrompt });
6973
+ * ```
6974
+ *
6975
+ * The ejected prompt owns the **semantic** layer — what the app is, how to act,
6976
+ * and what each surface means. The Muhkoo runtime separately appends the
6977
+ * **authoritative** roster (exact columns, function parameters, and the closed
6978
+ * list of callable tools), so the prompt here never needs to restate schema and
6979
+ * can't drift from it. Decorators only describe; they never change runtime
6980
+ * behavior, so they're safe to apply to a throwaway descriptor class.
6981
+ *
6982
+ * Requires `experimentalDecorators` (already enabled in this package). Metadata
6983
+ * is captured in a per-class registry — no `reflect-metadata` dependency.
6984
+ */
6985
+ // Per-class metadata store, keyed by the class constructor. Member decorators
6986
+ // run during class-body evaluation (before the class decorator), so each
6987
+ // decorator get-or-creates the descriptor and they all converge on one entry.
6988
+ const REGISTRY = new WeakMap();
6989
+ function descriptorFor(ctor) {
6990
+ let d = REGISTRY.get(ctor);
6991
+ if (!d) {
6992
+ d = { spaces: [], tables: [], functions: [] };
6993
+ REGISTRY.set(ctor, d);
6994
+ }
6995
+ return d;
6996
+ }
6997
+ /** Resolve the owning class constructor from a decorator `target` — the
6998
+ * prototype for instance members, the constructor itself for static ones. */
6999
+ function ctorOf(target) {
7000
+ return typeof target === "function" ? target : target.constructor;
7001
+ }
7002
+ /**
7003
+ * Class decorator. Declares the app's agent identity, purpose, and behavioral
7004
+ * guidance. Apply it to the class whose members carry the surface decorators.
7005
+ */
7006
+ function MuhkooAgent(meta) {
7007
+ return (target) => {
7008
+ descriptorFor(target).agent = meta;
7009
+ };
7010
+ }
7011
+ /** Member decorator. Marks a channel/Space the agent can resolve and post to. */
7012
+ function MuhkooSpace(meta) {
7013
+ return ((target, propertyKey) => {
7014
+ descriptorFor(ctorOf(target)).spaces.push({
7015
+ name: meta.name ?? String(propertyKey),
7016
+ description: meta.description,
7017
+ });
7018
+ });
7019
+ }
7020
+ /** Member decorator. Marks an app database table the agent can query/mutate. */
7021
+ function MuhkooDB(meta) {
7022
+ return ((target, propertyKey) => {
7023
+ descriptorFor(ctorOf(target)).tables.push({
7024
+ table: meta.table ?? String(propertyKey),
7025
+ access: meta.access ?? "read",
7026
+ description: meta.description,
7027
+ });
7028
+ });
7029
+ }
7030
+ /** Member decorator. Marks a serverless function the agent can call. */
7031
+ function MuhkooFunction(meta) {
7032
+ return ((target, propertyKey) => {
7033
+ descriptorFor(ctorOf(target)).functions.push({
7034
+ name: meta.name ?? String(propertyKey),
7035
+ description: meta.description,
7036
+ });
7037
+ });
7038
+ }
7039
+ /** Read back the raw descriptor a class accumulated (for tooling/tests). */
7040
+ function getMuhkooAppDescriptor(appClass) {
7041
+ return REGISTRY.get(appClass);
7042
+ }
7043
+ /**
7044
+ * Compose the agent system prompt from a `@MuhkooAgent`-decorated class. Throws
7045
+ * if the class isn't decorated. The result is the semantic layer only — the
7046
+ * runtime appends exact schema + the closed tool list at invocation time.
7047
+ */
7048
+ function ejectAgentPrompt(appClass) {
7049
+ const d = REGISTRY.get(appClass);
7050
+ if (!d || !d.agent) {
7051
+ throw new Error("ejectAgentPrompt: the class must be decorated with @MuhkooAgent");
7052
+ }
7053
+ const { agent } = d;
7054
+ const lines = [];
7055
+ lines.push(`You are ${agent.name}. ${agent.purpose}`.trim());
7056
+ if (agent.guidance?.length) {
7057
+ lines.push("", "Guidance:");
7058
+ for (const g of agent.guidance)
7059
+ lines.push(`- ${g}`);
7060
+ }
7061
+ if (d.spaces.length) {
7062
+ lines.push("", "Channels (Spaces) you can resolve with resolve_channel and post messages into:");
7063
+ for (const s of d.spaces)
7064
+ lines.push(`- ${s.name}: ${s.description}`);
7065
+ }
7066
+ if (d.tables.length) {
7067
+ lines.push("", "App database tables:");
7068
+ for (const t of d.tables) {
7069
+ const verbs = t.access === "write"
7070
+ ? "read & write — db_query/db_get/db_insert/db_update/db_delete"
7071
+ : "read-only — db_query/db_get";
7072
+ lines.push(`- ${t.table} (${verbs}): ${t.description}`);
7073
+ }
7074
+ }
7075
+ if (d.functions.length) {
7076
+ lines.push("", "Functions you can invoke with call_function:");
7077
+ for (const f of d.functions)
7078
+ lines.push(`- ${f.name}: ${f.description}`);
7079
+ }
7080
+ if (agent.instructions?.trim()) {
7081
+ lines.push("", agent.instructions.trim());
7082
+ }
7083
+ // How to respond — the load-bearing behavioral contract. Without this, models
7084
+ // (especially gpt-oss) tend to run tool calls and then end their turn with no
7085
+ // user-facing message, so the user sees the work happen but gets no reply.
7086
+ const hasTools = d.tables.length > 0 || d.functions.length > 0;
7087
+ lines.push("", "How to respond:");
7088
+ if (hasTools) {
7089
+ lines.push("- When you need information or need to make a change, call your tools immediately — don't ask the user to do it, and don't describe or name the tools to them.", "- After your tool calls return, you MUST send one final reply to the channel, in plain language, that answers the request using the results.");
7090
+ }
7091
+ lines.push("- Always end your turn with a short written reply (one or two sentences). Never finish with only tool calls and no message, and never reply with an empty message.", "- Don't restate function names, parameters, JSON, or your list of tools to the user — just give them the answer.");
7092
+ lines.push("", "The exact columns, function parameters, and the full list of callable tools are supplied to you by the runtime. Follow that authoritative list — never invent tables, columns, functions, or tools.");
7093
+ return lines.join("\n");
7094
+ }
7095
+ /**
7096
+ * Derive a suggested tools allowlist from a decorated class — the db tables
7097
+ * (and whether any are writable), the callable functions, and whether channels
7098
+ * are in play. Pair with {@link ejectAgentPrompt} when configuring the agent.
7099
+ *
7100
+ * If any tables/functions are present the result has `enabled: true`; to
7101
+ * actually grant tools you must also pass a function-calling `model` in the same
7102
+ * `client.agents.create`/`update` call (the server enforces this).
7103
+ */
7104
+ function ejectAgentTools(appClass, opts) {
7105
+ const d = REGISTRY.get(appClass);
7106
+ if (!d) {
7107
+ throw new Error("ejectAgentTools: the class must be decorated with @MuhkooAgent");
7108
+ }
7109
+ const anyWrite = d.tables.some((t) => t.access === "write");
7110
+ const mode = d.tables.length === 0 ? "off" : anyWrite ? "write" : "read";
7111
+ return {
7112
+ enabled: d.tables.length > 0 || d.functions.length > 0 || d.spaces.length > 0,
7113
+ db: { mode, tables: d.tables.map((t) => t.table) },
7114
+ functions: d.functions.map((f) => f.name),
7115
+ channels: d.spaces.length > 0,
7116
+ maxIterations: opts?.maxIterations ?? 6,
7117
+ };
7118
+ }
7119
+
6855
7120
  const appLogger$1 = new Logger("connect", 'ERROR');
6856
7121
  globalThis.appLogger = appLogger$1;
6857
7122
 
@@ -7388,5 +7653,5 @@ var bundledLoader = /*#__PURE__*/Object.freeze({
7388
7653
  default: loadRsWasm
7389
7654
  });
7390
7655
 
7391
- 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, Logger, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, Ready, ReedSolomonCodec, Retry, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, WSTransport, ZkAuth, _accountId, _formatBytes, _messageId, _objectId, _packetId, _socketId, _userId, appLogger$1 as appLogger, assertType, base58Decode, base58Encode, buildCommitment, compilePrograms, concatBytes, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deserialize, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, fromBase64, fromBase64Url, fromHex, generateAuthProof, generateChecksum, generateId, getIPAddress, getId, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, isNumber, log, manifestToStat, poseidonHash, quickVerify, randomBytes, serialize, shardHash, signMessage, toBase64, toBase64Url, toField, toHex, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
7656
+ 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, DbNamespace, DbTable, DoubleRatchet, DoubleRatchetCipher, DoubleRatchetManager, EncryptedSession, EventCore, EventCoreEvents, Field, Field as FieldElement, FileStorage, FunctionsNamespace, HashKnowledge, HttpClient, HttpError, KEEPER_MEMBER_ID, KeyStore, KeyringClient, KvNamespace, LocalStorageSessionStore, Logger, MemorySessionStore, Message, Message as MessageDefault, MessageNamespace, MuhkooAgent, MuhkooDB, MuhkooFunction, MuhkooSpace, PBKDF2_DEFAULT_ITERATIONS, PREIMAGE_POK_VERIFICATION_KEY, Packet, PersonalSpaceClient, Poseidon, PreimagePoK, Ready, ReedSolomonCodec, Retry, Space as Room, SerializeMessage, SessionState, ShardClient, SharedSpaceClient, Space, SpaceKeyring, SpaceNamespace, SpacePacketCipher, StorageNamespace, WSTransport, ZkAuth, _accountId, _formatBytes, _messageId, _objectId, _packetId, _socketId, _userId, appLogger$1 as appLogger, assertType, base58Decode, base58Encode, buildCommitment, compilePrograms, concatBytes, decodeFromHex, decorators, decryptAesGcm, defaultCircuitUrls, defaultSessionStore, deriveAesKeyFromPassphrase, deriveBitsHkdf, deriveIdentity, deserialize, ejectAgentPrompt, ejectAgentTools, encodeToHex, encryptAesGcm, exportPublicKeyBase64, exportPublicKeyHex, fromBase64, fromBase64Url, fromHex, generateAuthProof, generateChecksum, generateId, getIPAddress, getId, getMuhkooAppDescriptor, getSubtle, initBn128Wasm, initRsWasm, initializeCircuits, isNumber, log, manifestToStat, poseidonHash, quickVerify, randomBytes, serialize, shardHash, signMessage, toBase64, toBase64Url, toField, toHex, unwrapWithPassphrase, utf8Decode, utf8Encode, verify, verifyChecksum, verifyGroth16, verifyHashKnowledge, verifyPreimagePoK, wrapWithPassphrase };
7392
7657
  //# sourceMappingURL=index.js.map