primitive-functions 0.2.1 → 0.3.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.
Files changed (2) hide show
  1. package/index.d.ts +257 -74
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -110,11 +110,17 @@ export interface HeaderResult {
110
110
  export interface PrimitivePlatformError extends Error {
111
111
  status: number;
112
112
  errorCode: string | null;
113
+ /**
114
+ * The route's structured `details`, or null when its refusal carries none
115
+ * (#3803). `AGENT_SESSION_VARIABLES_INVALID` lists `errors` as
116
+ * `{ path, message }`; `AGENT_SESSION_ORIGIN_REFUSED` names `origin`.
117
+ */
118
+ details: unknown;
113
119
  }
114
120
 
115
121
  /**
116
122
  * The typed HTTP profile, generated from the platform's OpenAPI document. Its
117
- * namespaces mirror the operation ids: analytics, blobBuckets, channels, collections, configVars, connections, databaseTypeConfigs, databases, documents, email, functions, groups, integrations, locks, notifications, prompts, resourceMetadata, secrets, users.
123
+ * namespaces mirror the operation ids: agentSessions, analytics, blobBuckets, channels, collections, configVars, connections, databaseTypeConfigs, databases, documents, email, functions, groups, integrations, locks, notifications, prompts, resourceMetadata, secrets, users.
118
124
  * Methods take one options object carrying the operation's path parameters,
119
125
  * query parameters, request headers (under their wire names) and `body`.
120
126
  *
@@ -131,6 +137,43 @@ export interface PrimitivePlatformError extends Error {
131
137
  * stays refused: same-run composition is an import.
132
138
  */
133
139
  export interface FunctionApi {
140
+ "agentSessions": {
141
+ /** `agentSessions.addMember` — POST /agent-sessions/{sessionId}/members. Add a member to an agent session, or change their role */
142
+ "addMember"(args: {
143
+ "sessionId": string | number;
144
+ body: unknown;
145
+ }): Promise<any>;
146
+ /** `agentSessions.create` — POST /agent-sessions. Create an agent session (ctx.agents.createSession) */
147
+ "create"(args: {
148
+ body: unknown;
149
+ }): Promise<any>;
150
+ /** `agentSessions.delete` — DELETE /agent-sessions/{sessionId}. Delete an agent session */
151
+ "delete"(args: {
152
+ "sessionId": string | number;
153
+ }): Promise<any>;
154
+ /** `agentSessions.get` — GET /agent-sessions/{sessionId}. Get an agent session */
155
+ "get"(args: {
156
+ "sessionId": string | number;
157
+ }): Promise<any>;
158
+ /** `agentSessions.list` — GET /agent-sessions. List one user's agent sessions */
159
+ "list"(args?: {
160
+ "userId"?: string | number | boolean;
161
+ "agent"?: string | number | boolean;
162
+ "scope"?: string | number | boolean;
163
+ "limit"?: string | number | boolean;
164
+ "cursor"?: string | number | boolean;
165
+ }): Promise<any>;
166
+ /** `agentSessions.removeMember` — DELETE /agent-sessions/{sessionId}/members/{userId}. Remove a member from an agent session */
167
+ "removeMember"(args: {
168
+ "sessionId": string | number;
169
+ "userId": string | number;
170
+ }): Promise<any>;
171
+ /** `agentSessions.rename` — PATCH /agent-sessions/{sessionId}. Rename an agent session */
172
+ "rename"(args: {
173
+ "sessionId": string | number;
174
+ body: unknown;
175
+ }): Promise<any>;
176
+ };
134
177
  "analytics": {
135
178
  /** `analytics.cohortRetention` — GET /analytics/cohort-retention. Cohort retention metrics */
136
179
  "cohortRetention"(args?: {
@@ -509,56 +552,6 @@ export interface FunctionApi {
509
552
  "databaseId": string | number;
510
553
  body: unknown;
511
554
  }): Promise<any>;
512
- "adminData": {
513
- /**
514
- * `databases.adminData.batch` — POST /databases/{databaseId}/admin-data/batch. DEPRECATED — direct database batch; use databases/{databaseId}/records/batch
515
- * @deprecated Use databases/{databaseId}/records/batch
516
- */
517
- "batch"(args: {
518
- "databaseId": string | number;
519
- body: unknown;
520
- }): Promise<any>;
521
- /**
522
- * `databases.adminData.count` — POST /databases/{databaseId}/admin-data/count. DEPRECATED — direct database count; use databases/{databaseId}/records/count
523
- * @deprecated Use databases/{databaseId}/records/count
524
- */
525
- "count"(args: {
526
- "databaseId": string | number;
527
- body: unknown;
528
- }): Promise<any>;
529
- /**
530
- * `databases.adminData.delete` — POST /databases/{databaseId}/admin-data/delete. DEPRECATED — direct database delete; use databases/{databaseId}/records/delete
531
- * @deprecated Use databases/{databaseId}/records/delete
532
- */
533
- "delete"(args: {
534
- "databaseId": string | number;
535
- body: unknown;
536
- }): Promise<any>;
537
- /**
538
- * `databases.adminData.patch` — POST /databases/{databaseId}/admin-data/patch. DEPRECATED — direct database patch; use databases/{databaseId}/records/patch
539
- * @deprecated Use databases/{databaseId}/records/patch
540
- */
541
- "patch"(args: {
542
- "databaseId": string | number;
543
- body: unknown;
544
- }): Promise<any>;
545
- /**
546
- * `databases.adminData.query` — POST /databases/{databaseId}/admin-data/query. DEPRECATED — direct database query; use databases/{databaseId}/records/query
547
- * @deprecated Use databases/{databaseId}/records/query
548
- */
549
- "query"(args: {
550
- "databaseId": string | number;
551
- body: unknown;
552
- }): Promise<any>;
553
- /**
554
- * `databases.adminData.save` — POST /databases/{databaseId}/admin-data/save. DEPRECATED — direct database save; use databases/{databaseId}/records/save
555
- * @deprecated Use databases/{databaseId}/records/save
556
- */
557
- "save"(args: {
558
- "databaseId": string | number;
559
- body: unknown;
560
- }): Promise<any>;
561
- };
562
555
  /** `databases.create` — POST /databases. Create a database */
563
556
  "create"(args: {
564
557
  body: unknown;
@@ -584,13 +577,6 @@ export interface FunctionApi {
584
577
  "get"(args: {
585
578
  "databaseId": string | number;
586
579
  }): Promise<any>;
587
- /**
588
- * `databases.getMetadata` — GET /databases/{databaseId}/metadata. DEPRECATED — get database metadata; use resource metadata categories (resources/database/:databaseId/metadata/:category)
589
- * @deprecated Use resource metadata categories (resources/database/:databaseId/metadata/:category)
590
- */
591
- "getMetadata"(args: {
592
- "databaseId": string | number;
593
- }): Promise<any>;
594
580
  /** `databases.grantGroupPermission` — POST /databases/{databaseId}/group-permissions. Grant a group permission on a database */
595
581
  "grantGroupPermission"(args: {
596
582
  "databaseId": string | number;
@@ -744,14 +730,6 @@ export interface FunctionApi {
744
730
  "databaseId": string | number;
745
731
  body: unknown;
746
732
  }): Promise<any>;
747
- /**
748
- * `databases.updateMetadata` — PATCH /databases/{databaseId}/metadata. DEPRECATED — update database metadata; use resource metadata categories (resources/database/:databaseId/metadata/:category)
749
- * @deprecated Use resource metadata categories (resources/database/:databaseId/metadata/:category)
750
- */
751
- "updateMetadata"(args: {
752
- "databaseId": string | number;
753
- body: unknown;
754
- }): Promise<any>;
755
733
  };
756
734
  "documents": {
757
735
  /** `documents.abortIngest` — POST /documents/{documentId}/ingest/{sessionId}/abort. Abort a bulk-load session before its swap */
@@ -830,13 +808,6 @@ export interface FunctionApi {
830
808
  "X-Blob-Sha256": string | number;
831
809
  body: ArrayBuffer | Uint8Array | string;
832
810
  }): Promise<any>;
833
- /**
834
- * `documents.blobs.uploadWithoutId` — PUT /documents/{documentId}/blobs. Deprecated: upload a document blob without a client-specified id
835
- * @deprecated Deprecated in the app API spec; see its description.
836
- */
837
- "uploadWithoutId"(args: {
838
- "documentId": string | number;
839
- }): Promise<any>;
840
811
  };
841
812
  /** `documents.clearLinkAccess` — DELETE /documents/{documentId}/link-access. Turn off the document's link access */
842
813
  "clearLinkAccess"(args: {
@@ -1247,7 +1218,7 @@ export interface FunctionApi {
1247
1218
  "status"(args: {
1248
1219
  body: unknown;
1249
1220
  }): Promise<any>;
1250
- /** `locks.tryAcquire` — POST /locks/acquire. Attempt to acquire a named lock (single non-blocking attempt) */
1221
+ /** `locks.tryAcquire` — POST /locks/acquire. Attempt to acquire a named lock (one attempt, or with waitMs a bounded server-side wait) */
1251
1222
  "tryAcquire"(args: {
1252
1223
  body: unknown;
1253
1224
  }): Promise<any>;
@@ -1744,6 +1715,102 @@ export type AgentVariables<K extends AgentKeys> = PromptSchemas[K] extends {
1744
1715
  ? V
1745
1716
  : never;
1746
1717
 
1718
+ /**
1719
+ * The keys `ctx.agents.createSession` accepts — #3803: every declared agent,
1720
+ * or `string` before the tree has pushed any prompt (the `PromptKeys`
1721
+ * rule).
1722
+ */
1723
+ export type SessionAgentKeys = [keyof PromptSchemas] extends [never]
1724
+ ? string
1725
+ : AgentKeys;
1726
+
1727
+ /**
1728
+ * What `ctx.agents.createSession` takes — #3803. Typed by the agent's key:
1729
+ * `variables` is that agent's `inputSchema` (any object before a push),
1730
+ * and the platform validates it again against the schema as pushed.
1731
+ */
1732
+ export interface AgentSessionCreateOptions<K extends SessionAgentKeys> {
1733
+ /** The key of an agent prompt (`kind = "agent"`). */
1734
+ agent: K;
1735
+ /** The session's variables; at most 16 KiB of JSON. */
1736
+ variables?: K extends AgentKeys ? AgentVariables<K> : Record<string, unknown>;
1737
+ /** Free text the app groups sessions by, 1 to 256 characters. */
1738
+ scope?: string;
1739
+ /** 1 to 255 characters; defaults to the agent's display name. */
1740
+ title?: string;
1741
+ /**
1742
+ * Initial participants, who send messages and hold a `read-write` grant
1743
+ * on the session's document — #3805. Existing users of this app, not the
1744
+ * caller; with `viewers`, at most 50.
1745
+ */
1746
+ participants?: string[];
1747
+ /**
1748
+ * Initial viewers, who read the session and hold a `reader` grant — #3805.
1749
+ * Existing users of this app, not the caller, in neither list twice.
1750
+ */
1751
+ viewers?: string[];
1752
+ }
1753
+
1754
+ /** What `ctx.agents.createSession` answers — #3803. */
1755
+ export interface AgentSessionCreateResult {
1756
+ /** The session: what the app keeps and uses for everything but opening. */
1757
+ sessionId: string;
1758
+ /** The session's conversation document, opened with the document client. */
1759
+ documentId: string;
1760
+ }
1761
+
1762
+ /** What `ctx.agents.getSession` answers — #3805. Never the document's rows. */
1763
+ export interface AgentSessionInfo {
1764
+ sessionId: string;
1765
+ agentKey: string;
1766
+ /** Open this with the document client to read the conversation. */
1767
+ documentId: string;
1768
+ ownerUserId: string;
1769
+ /** ISO-8601. */
1770
+ createdAt: string;
1771
+ title: string | null;
1772
+ scope: string | null;
1773
+ /** ISO-8601; null when the session's listing row is missing. */
1774
+ lastActivityAt: string | null;
1775
+ /** The members, in the order they were added. */
1776
+ members: { viewers: string[]; participants: string[] };
1777
+ /** The invoking user's standing on the session. */
1778
+ role: "owner" | "participant" | "viewer" | "admin";
1779
+ }
1780
+
1781
+ /** One session in `ctx.agents.listSessions` — #3805. */
1782
+ export interface AgentSessionListItem {
1783
+ sessionId: string;
1784
+ agentKey: string;
1785
+ scope: string | null;
1786
+ documentId: string;
1787
+ ownerUserId: string;
1788
+ role: "owner" | "participant" | "viewer";
1789
+ title: string | null;
1790
+ /** ISO-8601. */
1791
+ lastActivityAt: string;
1792
+ createdAt: string | null;
1793
+ }
1794
+
1795
+ /** What `ctx.agents.listSessions` takes — #3805. There is no user: it is always the invoking user. */
1796
+ export interface AgentSessionListOptions {
1797
+ /** Only this agent's sessions. */
1798
+ agent?: string;
1799
+ /** Only sessions created with exactly this scope. */
1800
+ scope?: string;
1801
+ /** Page size, at most 100 (default 50). */
1802
+ limit?: number;
1803
+ /** The `nextCursor` of the previous page. */
1804
+ cursor?: string;
1805
+ }
1806
+
1807
+ /** A page of `ctx.agents.listSessions` — #3805. */
1808
+ export interface AgentSessionListPage {
1809
+ items: AgentSessionListItem[];
1810
+ hasMore: boolean;
1811
+ nextCursor?: string;
1812
+ }
1813
+
1747
1814
  /** One agent's client tools, by name: each one's `input` and `output` (#3798). */
1748
1815
  export type AgentClientTools<K extends AgentKeys> = PromptSchemas[K] extends {
1749
1816
  agent: { clientTools: infer T };
@@ -1957,6 +2024,52 @@ export interface FunctionStartResult {
1957
2024
  existing?: boolean;
1958
2025
  }
1959
2026
 
2027
+ /** A held named lock, as `ctx.locks.acquire` hands it back — #3930. */
2028
+ export interface LockHandle {
2029
+ key: string;
2030
+ handleId: string;
2031
+ leaseExpiresAt: string;
2032
+ }
2033
+
2034
+ /** How long to hold, and how long to wait — #3930. */
2035
+ export interface LockAcquireOptions {
2036
+ /** The lease, in milliseconds (at most 24 h). Renew or release before it lapses. */
2037
+ ttlMs: number;
2038
+ /**
2039
+ * How long to wait for the key, in milliseconds, at most one hour. Under the
2040
+ * request runtime it must also fit the invocation's remaining budget.
2041
+ */
2042
+ timeoutMs: number;
2043
+ /**
2044
+ * Who this hold belongs to. Defaults to `ctx.runId` when the invocation
2045
+ * has a run, so a resumed slice re-takes its own hold with a fresh handle
2046
+ * rather than waiting on it.
2047
+ */
2048
+ owner?: string;
2049
+ }
2050
+
2051
+ /**
2052
+ * The answer to a blocking acquire — #3930. Never a throw for "not acquired":
2053
+ * a refusal carries the last contention seen, and `rateLimited` says the
2054
+ * last attempt was refused by the acquire rate limit rather than by a holder.
2055
+ */
2056
+ export type LockAcquireResult =
2057
+ | { acquired: true; handle: LockHandle }
2058
+ | {
2059
+ acquired: false;
2060
+ timedOut: true;
2061
+ rateLimited: boolean;
2062
+ heldBy: string | null;
2063
+ holderKind: string | null;
2064
+ owner: string | null;
2065
+ leaseExpiresAt: string | null;
2066
+ };
2067
+
2068
+ /** The answer to `ctx.locks.release`. */
2069
+ export type LockReleaseResult =
2070
+ | { released: true }
2071
+ | { released: false; reason: "not_holder" | "not_held" };
2072
+
1960
2073
  export interface FunctionContext {
1961
2074
  /** The HTTP caller, or null for a webhook or cron fire. */
1962
2075
  user: FunctionUser | null;
@@ -2079,6 +2192,35 @@ export interface FunctionContext {
2079
2192
  args?: PromptRunArgs
2080
2193
  ): Promise<PromptRunResult<K>>;
2081
2194
  };
2195
+ /**
2196
+ * Agent sessions (#3803, project `agents`).
2197
+ *
2198
+ * `createSession` creates a session owned by this invocation's caller and
2199
+ * answers `{ sessionId, documentId }`. It is allowed only in a run fired
2200
+ * over HTTP (`invoke`, or a `start` task) by a signed-in user; from a
2201
+ * manual run, a nested start, a workflow step, cron or a webhook it
2202
+ * rejects with `AGENT_SESSION_ORIGIN_REFUSED`, `details.origin` naming
2203
+ * it. Variables failing the agent's `inputSchema` reject with
2204
+ * `AGENT_SESSION_VARIABLES_INVALID` and `details.errors`.
2205
+ *
2206
+ * Once a tree has pushed, a key that is not an agent, and variables the
2207
+ * agent's schema refuses, are compile errors. `participants` and
2208
+ * `viewers` name initial members (#3805).
2209
+ *
2210
+ * `getSession` and `listSessions` (#3805) read the INVOKING user's
2211
+ * sessions — the ones they own or are a member of — and nobody else's,
2212
+ * whoever invoked the function; a session the user is not in answers
2213
+ * `AGENT_SESSION_NOT_FOUND`. Both have the same origin rule as
2214
+ * `createSession`. Renaming, deleting and changing members are the
2215
+ * owner's, from a client.
2216
+ */
2217
+ agents: {
2218
+ createSession<K extends SessionAgentKeys>(
2219
+ options: AgentSessionCreateOptions<K>
2220
+ ): Promise<AgentSessionCreateResult>;
2221
+ getSession(sessionId: string): Promise<AgentSessionInfo>;
2222
+ listSessions(options?: AgentSessionListOptions): Promise<AgentSessionListPage>;
2223
+ };
2082
2224
  /**
2083
2225
  * The value of one app secret, under a `secret:<NAME>` grant (#3183).
2084
2226
  *
@@ -2144,6 +2286,47 @@ export interface FunctionContext {
2144
2286
  ): Promise<ChannelGrantResult>;
2145
2287
  publish(channel: string, payload: unknown): Promise<SendResult>;
2146
2288
  };
2289
+ /**
2290
+ * Named locks that WAIT — #3930. `ctx.api.locks.tryAcquire` is one attempt;
2291
+ * these wait for the key, up to `timeoutMs` (at most one hour).
2292
+ *
2293
+ * The owner defaults to `ctx.runId`, so a run never waits on its own hold:
2294
+ * a resumed slice, or a second call on a key the run already holds, re-takes
2295
+ * it at once with a fresh handle.
2296
+ *
2297
+ * Under the TASK runtime the wait is durable: each attempt is a step that
2298
+ * asks the platform to wait server-side for up to 30 s, so a wait costs one
2299
+ * platform call and one acquire slot per half-minute, no CPU, and the
2300
+ * slice's budget is refreshed at every attempt. It is not a suspension — the
2301
+ * engine does not hibernate a wait shorter than five minutes. Under the
2302
+ * REQUEST runtime the whole wait must fit the invocation's remaining budget,
2303
+ * or the call fails `FUNCTION_RUNTIME_REFUSED` before any attempt (a
2304
+ * webhook delivery has 5 s): hand longer waits to a task with
2305
+ * `ctx.functions.start`.
2306
+ */
2307
+ locks: {
2308
+ /**
2309
+ * Wait for `key`. Answers `acquired: true` with the handle, or
2310
+ * `acquired: false, timedOut: true` with the last contention seen.
2311
+ */
2312
+ acquire(key: string, options: LockAcquireOptions): Promise<LockAcquireResult>;
2313
+ /** Release a handle `acquire` handed back. */
2314
+ release(handle: LockHandle): Promise<LockReleaseResult>;
2315
+ /**
2316
+ * Acquire, run `fn`, and release in `finally` — on a return and on a
2317
+ * throw. Answers `fn`'s value; `fn`'s own error propagates after the
2318
+ * release. Throws an error named `LOCK_TIMEOUT` (`code` the same, the
2319
+ * contention in `details`) without running `fn` when the key is not
2320
+ * acquired within `timeoutMs`. A nested `withLock` on the same key in
2321
+ * one run re-enters, and its release frees the outer hold: use distinct
2322
+ * keys, or one wrapper.
2323
+ */
2324
+ withLock<T>(
2325
+ key: string,
2326
+ options: LockAcquireOptions,
2327
+ fn: (handle: LockHandle) => Promise<T>
2328
+ ): Promise<T>;
2329
+ };
2147
2330
  }
2148
2331
 
2149
2332
  /** How the wait between one step's retries grows. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primitive-functions",
3
- "version": "0.2.1",
3
+ "version": "0.3.0-alpha.1",
4
4
  "description": "The module a Primitive server function imports. Supplied by the platform at invoke time; reserved here so the name is ours before the runtime lands.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Primitive LLC",