@deepraxis/cli 0.1.0-dev.67c7f3b → 0.1.0-dev.6898104
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/COMMANDS.md +11 -4
- package/dist/praxis.js +774 -215
- package/package.json +1 -1
package/dist/praxis.js
CHANGED
|
@@ -136,6 +136,27 @@ var operations = [
|
|
|
136
136
|
description: `Tool configurations available to the agent. Maximum of 128 tools
|
|
137
137
|
across all toolsets allowed.`
|
|
138
138
|
},
|
|
139
|
+
{
|
|
140
|
+
name: "databases",
|
|
141
|
+
type: "array",
|
|
142
|
+
itemType: "object",
|
|
143
|
+
required: false,
|
|
144
|
+
description: "Database allowlist for platform resources accessible through service-agent codemode. Only kind=service accepts nonempty bindings; personal agents return 400. At most 20 bindings per resource type, with no duplicate ids. Newly added bindings apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Unbound resources return 404; writes to read_only resources are refused. Other platform APIs return 403, except public API discovery. Invalid bindings and unknown item fields return 400. Omit on create for no bindings."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "vector_stores",
|
|
148
|
+
type: "array",
|
|
149
|
+
itemType: "object",
|
|
150
|
+
required: false,
|
|
151
|
+
description: "Knowledge vector store allowlist for platform resources accessible through service-agent codemode. Only kind=service accepts nonempty bindings; personal agents return 400. At most 20 bindings per resource type, with no duplicate ids. Newly added bindings apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Unbound resources return 404; writes to read_only resources are refused. Other platform APIs return 403, except public API discovery. Invalid bindings and unknown item fields return 400. Omit on create for no bindings."
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "files",
|
|
155
|
+
type: "array",
|
|
156
|
+
itemType: "object",
|
|
157
|
+
required: false,
|
|
158
|
+
description: "File allowlist for platform resources accessible through service-agent codemode. Only kind=service accepts nonempty bindings; personal agents return 400. At most 20 bindings per resource type, with no duplicate ids. Newly added bindings apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Unbound resources return 404; writes to read_only resources are refused. Other platform APIs return 403, except public API discovery. Invalid bindings and unknown item fields return 400. Omit on create for no bindings."
|
|
159
|
+
},
|
|
139
160
|
{
|
|
140
161
|
name: "kind",
|
|
141
162
|
type: "string",
|
|
@@ -183,6 +204,17 @@ across all toolsets allowed.`
|
|
|
183
204
|
type: "object",
|
|
184
205
|
required: false,
|
|
185
206
|
description: "Praxis extension: switchable model ids on /agent/v1 only. The default model must be included. When omitted, only the default model is selectable."
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "preset",
|
|
210
|
+
type: "string",
|
|
211
|
+
enum: [
|
|
212
|
+
"minimal",
|
|
213
|
+
"data-editor",
|
|
214
|
+
"full"
|
|
215
|
+
],
|
|
216
|
+
required: false,
|
|
217
|
+
description: "Optional tool preset. minimal enables read, glob, grep and ask_user_question; data-editor also enables write and edit; full uses the default toolset with always_allow. Explicit tools override matching preset entries. codemode requires bash and is absent from data-editor."
|
|
186
218
|
}
|
|
187
219
|
]
|
|
188
220
|
}
|
|
@@ -301,6 +333,27 @@ Obtain this value from a create or retrieve response. Must be at least 1 if
|
|
|
301
333
|
specified. When supplied, the request fails if it does not match the server's
|
|
302
334
|
current version; omit to apply the update unconditionally.`
|
|
303
335
|
},
|
|
336
|
+
{
|
|
337
|
+
name: "databases",
|
|
338
|
+
type: "array",
|
|
339
|
+
itemType: "object",
|
|
340
|
+
required: false,
|
|
341
|
+
description: "Replace this resource allowlist; omission preserves it, and null or [] clears it. Additions apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Only service agents accept nonempty bindings."
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: "vector_stores",
|
|
345
|
+
type: "array",
|
|
346
|
+
itemType: "object",
|
|
347
|
+
required: false,
|
|
348
|
+
description: "Replace this resource allowlist; omission preserves it, and null or [] clears it. Additions apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Only service agents accept nonempty bindings."
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: "files",
|
|
352
|
+
type: "array",
|
|
353
|
+
itemType: "object",
|
|
354
|
+
required: false,
|
|
355
|
+
description: "Replace this resource allowlist; omission preserves it, and null or [] clears it. Additions apply only to new sessions; disabling or removing a binding immediately revokes access in running sessions. Only service agents accept nonempty bindings."
|
|
356
|
+
},
|
|
304
357
|
{
|
|
305
358
|
name: "kind",
|
|
306
359
|
type: "string",
|
|
@@ -348,6 +401,17 @@ current version; omit to apply the update unconditionally.`
|
|
|
348
401
|
type: "object",
|
|
349
402
|
required: false,
|
|
350
403
|
description: "Praxis extension: switchable model ids on /agent/v1 only. The default model must be included. When omitted, only the default model is selectable."
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: "preset",
|
|
407
|
+
type: "string",
|
|
408
|
+
enum: [
|
|
409
|
+
"minimal",
|
|
410
|
+
"data-editor",
|
|
411
|
+
"full"
|
|
412
|
+
],
|
|
413
|
+
required: false,
|
|
414
|
+
description: "Optional tool preset. minimal enables read, glob, grep and ask_user_question; data-editor also enables write and edit; full uses the default toolset with always_allow. Explicit tools override matching preset entries. codemode requires bash and is absent from data-editor."
|
|
351
415
|
}
|
|
352
416
|
]
|
|
353
417
|
}
|
|
@@ -552,6 +616,23 @@ Removes the user from the blocklist; previously revoked tokens stay revoked. Ide
|
|
|
552
616
|
],
|
|
553
617
|
query: []
|
|
554
618
|
},
|
|
619
|
+
{
|
|
620
|
+
resource: "agent.agents.unarchive",
|
|
621
|
+
method: "create",
|
|
622
|
+
summary: "Unarchive Agent",
|
|
623
|
+
description: "Restore an archived agent without creating a configuration version. Already active agents are unchanged. Missing or inaccessible agents return 404. Use the returned agent id to create new sessions.",
|
|
624
|
+
http: "POST",
|
|
625
|
+
path: "/agent/v1/agents/{agent_id}/unarchive",
|
|
626
|
+
streaming: "no",
|
|
627
|
+
pagination: false,
|
|
628
|
+
pathParams: [
|
|
629
|
+
{
|
|
630
|
+
name: "agent_id",
|
|
631
|
+
sdkName: "agent_id"
|
|
632
|
+
}
|
|
633
|
+
],
|
|
634
|
+
query: []
|
|
635
|
+
},
|
|
555
636
|
{
|
|
556
637
|
resource: "agent.agents.versions",
|
|
557
638
|
method: "list",
|
|
@@ -763,7 +844,9 @@ Own-face superset: Managed Agents has no persistent Computer attachment director
|
|
|
763
844
|
summary: "Connect computer",
|
|
764
845
|
description: `Resume the computer and issue a sandbox connection.
|
|
765
846
|
|
|
766
|
-
Own-face extension: Managed Agents has no persistent Computer connection. Returns the public SDK sandbox_id, envd_access_token and template_id, plus the machine tier the computer is on now (light or heavy) and the lease that keeps it there (lease_id, lease_expires_at; lease_id is null when no lease exists). Keep the lease while the connection stays open: renew it about every 20 seconds (POST .../leases/{lease_id}/renew) and release it on close (DELETE .../leases/{lease_id}). An unrenewed lease simply expires, and the full machine is reclaimed only after that. Archived computers remain accessible; foreign or absent computers return 404. Never cache credentials
|
|
847
|
+
Own-face extension: Managed Agents has no persistent Computer connection. Returns the public SDK sandbox_id, envd_access_token and template_id, plus the machine tier the computer is on now (light or heavy) and the lease that keeps it there (lease_id, lease_expires_at; lease_id is null when no lease exists). Keep the lease while the connection stays open: renew it about every 20 seconds (POST .../leases/{lease_id}/renew) and release it on close (DELETE .../leases/{lease_id}). An unrenewed lease simply expires, and the full machine is reclaimed only after that. Archived computers remain accessible; foreign or absent computers return 404. Never cache credentials.
|
|
848
|
+
|
|
849
|
+
Connect to a computer with a caller-held lease. Omit the body or send {} to request light: the lightweight shell, or the heavy instance while it is running. Send {"need":"heavy"} to request full Linux for interactive programs; files are synchronized before the heavy connection is returned with tier heavy. Renew the lease while using the connection and release it with DELETE when finished.`,
|
|
767
850
|
http: "POST",
|
|
768
851
|
path: "/agent/v1/computers/{computer_id}/connect",
|
|
769
852
|
streaming: "no",
|
|
@@ -774,7 +857,22 @@ Own-face extension: Managed Agents has no persistent Computer connection. Return
|
|
|
774
857
|
sdkName: "computer_id"
|
|
775
858
|
}
|
|
776
859
|
],
|
|
777
|
-
query: []
|
|
860
|
+
query: [],
|
|
861
|
+
body: {
|
|
862
|
+
required: false,
|
|
863
|
+
fields: [
|
|
864
|
+
{
|
|
865
|
+
name: "need",
|
|
866
|
+
type: "string",
|
|
867
|
+
enum: [
|
|
868
|
+
"light",
|
|
869
|
+
"heavy"
|
|
870
|
+
],
|
|
871
|
+
required: false,
|
|
872
|
+
description: "Defaults to light. light uses the lightweight shell, or the heavy instance while it is running. heavy requests a full Linux computer for interactive programs; heavy running time counts toward the daily budget in seconds."
|
|
873
|
+
}
|
|
874
|
+
]
|
|
875
|
+
}
|
|
778
876
|
},
|
|
779
877
|
{
|
|
780
878
|
resource: "agent.computers.files",
|
|
@@ -1821,7 +1919,7 @@ owning account only.`
|
|
|
1821
1919
|
resource: "agent.sessions",
|
|
1822
1920
|
method: "create",
|
|
1823
1921
|
summary: "Create session",
|
|
1824
|
-
description: `Create a session: one conversation with an agent
|
|
1922
|
+
description: `Create a session: one conversation with an agent. Pass agent as an agent id (latest version) or {id, version, type:"agent"}. Unlike Anthropic Managed Agents, omit environment_id to get a light machine, unless computer_id (explicit, or the agent's default) selects a Computer; pass an environment id for a sandbox recipe. For service agents, omission returns environment_id=light; explicit null allocates no machine, so codemode, bash and other machine tools are unavailable. Optional model must be one of the agent's allowed models; optional thinking is {effort: low|medium|high|xhigh|max|none} or null, where null inherits the agent default and then the model default (none requires the model to allow disabling thinking). Selections are saved before initial_events run; invalid ones return 400 invalid_request_error. Inline agent overrides are not supported. Supports vault_ids, up to 50, owned by the current organization and not archived; credential injection is deferred to a later version. Omitted budget defaults to USD 20; null removes the limit, and a limit object uses a positive integer string of USD cents. Up to 500 file resources can be attached. Use initial_events to send a first user.message in this request, or send messages afterwards with sessions.events.send. The returned status can still be idle before initial events run; read agent.message and the subsequent session.status_idle event to confirm completion.`,
|
|
1825
1923
|
http: "POST",
|
|
1826
1924
|
path: "/agent/v1/sessions",
|
|
1827
1925
|
streaming: "no",
|
|
@@ -1841,7 +1939,7 @@ owning account only.`
|
|
|
1841
1939
|
name: "environment_id",
|
|
1842
1940
|
type: "string",
|
|
1843
1941
|
required: false,
|
|
1844
|
-
description: "
|
|
1942
|
+
description: "Execution environment id from agent.environments.list or agent.environments.create. For a service agent, omission selects the built-in light environment and returns session.environment_id=light; explicit null allocates no machine and makes machine tools, including codemode and bash, unavailable. Personal agents use their selected Computer."
|
|
1845
1943
|
},
|
|
1846
1944
|
{
|
|
1847
1945
|
name: "budget",
|
|
@@ -1921,6 +2019,23 @@ offsets ("+08:00") and unknown names return 400. Never stored in
|
|
|
1921
2019
|
]
|
|
1922
2020
|
}
|
|
1923
2021
|
},
|
|
2022
|
+
{
|
|
2023
|
+
resource: "agent.sessions",
|
|
2024
|
+
method: "delete",
|
|
2025
|
+
summary: "Delete session",
|
|
2026
|
+
description: "Delete an idle or terminated session and its event history after saving a deletion snapshot. Supply the session id from creation or listing. Running sessions return 409 INVALID_STATE: interrupt first or wait until idle or terminated. Afterwards retrieval and event listing return 404 and lists omit the session. Example: DELETE /agent/v1/sessions/sesn_example.",
|
|
2027
|
+
http: "DELETE",
|
|
2028
|
+
path: "/agent/v1/sessions/{session_id}",
|
|
2029
|
+
streaming: "no",
|
|
2030
|
+
pagination: false,
|
|
2031
|
+
pathParams: [
|
|
2032
|
+
{
|
|
2033
|
+
name: "session_id",
|
|
2034
|
+
sdkName: "session_id"
|
|
2035
|
+
}
|
|
2036
|
+
],
|
|
2037
|
+
query: []
|
|
2038
|
+
},
|
|
1924
2039
|
{
|
|
1925
2040
|
resource: "agent.sessions",
|
|
1926
2041
|
method: "retrieve",
|
|
@@ -3435,6 +3550,27 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
3435
3550
|
],
|
|
3436
3551
|
query: []
|
|
3437
3552
|
},
|
|
3553
|
+
{
|
|
3554
|
+
resource: "application.workers.versions.assets",
|
|
3555
|
+
method: "retrieveManifest",
|
|
3556
|
+
summary: "Get version asset manifest",
|
|
3557
|
+
description: "Read the retained asset paths, content hashes and byte sizes of a version for publication planning. This read creates no session or version. A version without assets returns an empty manifest; unavailable artifacts and foreign resources return 404.",
|
|
3558
|
+
http: "GET",
|
|
3559
|
+
path: "/application/v1/workers/{worker_id}/versions/{version_id}/assets/manifest",
|
|
3560
|
+
streaming: "no",
|
|
3561
|
+
pagination: false,
|
|
3562
|
+
pathParams: [
|
|
3563
|
+
{
|
|
3564
|
+
name: "worker_id",
|
|
3565
|
+
sdkName: "worker_id"
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
name: "version_id",
|
|
3569
|
+
sdkName: "version_id"
|
|
3570
|
+
}
|
|
3571
|
+
],
|
|
3572
|
+
query: []
|
|
3573
|
+
},
|
|
3438
3574
|
{
|
|
3439
3575
|
resource: "automation.actions",
|
|
3440
3576
|
method: "list",
|
|
@@ -6858,7 +6994,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
6858
6994
|
name: "{column}",
|
|
6859
6995
|
type: "string",
|
|
6860
6996
|
required: false,
|
|
6861
|
-
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns.
|
|
6997
|
+
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
|
|
6862
6998
|
},
|
|
6863
6999
|
{
|
|
6864
7000
|
name: "and",
|
|
@@ -6906,7 +7042,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
6906
7042
|
name: "on_conflict",
|
|
6907
7043
|
type: "string",
|
|
6908
7044
|
required: false,
|
|
6909
|
-
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7045
|
+
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
6910
7046
|
},
|
|
6911
7047
|
{
|
|
6912
7048
|
name: "columns",
|
|
@@ -6920,7 +7056,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
6920
7056
|
resource: "database.databases.rest",
|
|
6921
7057
|
method: "retrieve",
|
|
6922
7058
|
summary: "Select rows",
|
|
6923
|
-
description: "Read matching rows with filters, selected columns and ordering. Returns at most 1000 rows per request, including when limit is omitted. Content-Range reports the actual returned interval and the total when count is requested. PATCH and DELETE are not subject to this read cap. Unlike Supabase, casts, aggregates, spread and join modifiers are unsupported. Each table supports up to 1,000,000 rows. Query budget: 8,000 ms with a shared 3,000,000-row safety ceiling. Create indexes on filtered or sorted fields, or narrow the request when it exceeds its budget. Synchronous SQLite aggregates use candidate-row throughput estimates before execution; deployed Workers freeze clocks during synchronous CPU work, so the timer is not a guaranteed server-side interrupt. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Error table: QUERY_CANCELED / PostgREST 57014 is HTTP 500, retryable=false: Query timed out: index filtered or sorted fields, or narrow the range. DATABASE_INVALID_STATE is HTTP 409 for operations on a deleting database. Cleared or nonexistent databases return DATABASE_NOT_FOUND / HTTP 404. The count is an HTTP Content-Range response header, not a JSON property.
|
|
7059
|
+
description: "Read matching rows with filters, selected columns and ordering. Returns at most 1000 rows per request, including when limit is omitted. Content-Range reports the actual returned interval and the total when count is requested. PATCH and DELETE are not subject to this read cap. Unlike Supabase, casts, aggregates, spread and join modifiers are unsupported. Each table supports up to 1,000,000 rows. Query budget: 8,000 ms with a shared 3,000,000-row safety ceiling. Create indexes on filtered or sorted fields, or narrow the request when it exceeds its budget. Synchronous SQLite aggregates use candidate-row throughput estimates before execution; deployed Workers freeze clocks during synchronous CPU work, so the timer is not a guaranteed server-side interrupt. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Error table: QUERY_CANCELED / PostgREST 57014 is HTTP 500, retryable=false: Query timed out: index filtered or sorted fields, or narrow the range. DATABASE_INVALID_STATE is HTTP 409 for operations on a deleting database. Cleared or nonexistent databases return DATABASE_NOT_FOUND / HTTP 404. The count is an HTTP Content-Range response header, not a JSON property. Use praxis.database.count in the SDK or codemode to return { count: number | null }; a page length is not a total unless you know all matches fit in that page.",
|
|
6924
7060
|
http: "GET",
|
|
6925
7061
|
path: "/database/v1/databases/{database_id}/rest/{table}",
|
|
6926
7062
|
streaming: "no",
|
|
@@ -6946,7 +7082,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
6946
7082
|
name: "{column}",
|
|
6947
7083
|
type: "string",
|
|
6948
7084
|
required: false,
|
|
6949
|
-
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns.
|
|
7085
|
+
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
|
|
6950
7086
|
},
|
|
6951
7087
|
{
|
|
6952
7088
|
name: "and",
|
|
@@ -6994,7 +7130,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
6994
7130
|
name: "on_conflict",
|
|
6995
7131
|
type: "string",
|
|
6996
7132
|
required: false,
|
|
6997
|
-
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7133
|
+
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
6998
7134
|
},
|
|
6999
7135
|
{
|
|
7000
7136
|
name: "columns",
|
|
@@ -7008,7 +7144,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7008
7144
|
resource: "database.databases.rest",
|
|
7009
7145
|
method: "head",
|
|
7010
7146
|
summary: "Count rows",
|
|
7011
|
-
description: "Inspect the HTTP row count and range without retrieving row data; send Prefer: count=exact for a filtered count. Returns no body and does not fetch or serialize row data. A known count determines the interval using limit/offset or Range with a default and maximum page size of 1000. Without a count preference, or when the selected count mode cannot supply a total, Content-Range is */*. Singular Accept still validates page cardinality. Unlike Supabase, planned and estimated counts do not use PostgreSQL planner estimates. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode.
|
|
7147
|
+
description: "Inspect the HTTP row count and range without retrieving row data; send Prefer: count=exact for a filtered count. Returns no body and does not fetch or serialize row data. A known count determines the interval using limit/offset or Range with a default and maximum page size of 1000. Without a count preference, or when the selected count mode cannot supply a total, Content-Range is */*. Singular Accept still validates page cardinality. Unlike Supabase, planned and estimated counts do not use PostgreSQL planner estimates. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Use praxis.database.count in the SDK or codemode to return { count: number | null } from this header without retrieving rows.",
|
|
7012
7148
|
http: "HEAD",
|
|
7013
7149
|
path: "/database/v1/databases/{database_id}/rest/{table}",
|
|
7014
7150
|
streaming: "no",
|
|
@@ -7034,7 +7170,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7034
7170
|
name: "{column}",
|
|
7035
7171
|
type: "string",
|
|
7036
7172
|
required: false,
|
|
7037
|
-
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns.
|
|
7173
|
+
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
|
|
7038
7174
|
},
|
|
7039
7175
|
{
|
|
7040
7176
|
name: "and",
|
|
@@ -7082,7 +7218,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7082
7218
|
name: "on_conflict",
|
|
7083
7219
|
type: "string",
|
|
7084
7220
|
required: false,
|
|
7085
|
-
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7221
|
+
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7086
7222
|
},
|
|
7087
7223
|
{
|
|
7088
7224
|
name: "columns",
|
|
@@ -7122,7 +7258,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7122
7258
|
name: "{column}",
|
|
7123
7259
|
type: "string",
|
|
7124
7260
|
required: false,
|
|
7125
|
-
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns.
|
|
7261
|
+
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
|
|
7126
7262
|
},
|
|
7127
7263
|
{
|
|
7128
7264
|
name: "and",
|
|
@@ -7170,7 +7306,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7170
7306
|
name: "on_conflict",
|
|
7171
7307
|
type: "string",
|
|
7172
7308
|
required: false,
|
|
7173
|
-
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7309
|
+
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7174
7310
|
},
|
|
7175
7311
|
{
|
|
7176
7312
|
name: "columns",
|
|
@@ -7190,7 +7326,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
|
|
|
7190
7326
|
summary: "Insert rows",
|
|
7191
7327
|
description: `Insert rows into an existing table after defining its fields; at most 500 rows per request. Each request is atomic: any failure rolls back the entire batch. There are no transactions across requests.
|
|
7192
7328
|
Rows are filled to the union of their keys with null; send Prefer: missing=default to use field defaults for missing keys.
|
|
7193
|
-
The default is return=minimal: success returns HTTP 201 with an empty body. Send Prefer: return=representation to return the inserted rows. Unlike Supabase, upsert conflicts can target only id or one unique field, not a composite key. Each table supports up to 1,000,000 rows.`,
|
|
7329
|
+
The default is return=minimal: success returns HTTP 201 with an empty body. Send Prefer: return=representation to return the inserted rows. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. Unlike Supabase, upsert conflicts can target only id or one unique field, not a composite key. Each table supports up to 1,000,000 rows.`,
|
|
7194
7330
|
http: "POST",
|
|
7195
7331
|
path: "/database/v1/databases/{database_id}/rest/{table}",
|
|
7196
7332
|
streaming: "no",
|
|
@@ -7216,7 +7352,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7216
7352
|
name: "{column}",
|
|
7217
7353
|
type: "string",
|
|
7218
7354
|
required: false,
|
|
7219
|
-
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns.
|
|
7355
|
+
description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
|
|
7220
7356
|
},
|
|
7221
7357
|
{
|
|
7222
7358
|
name: "and",
|
|
@@ -7264,7 +7400,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7264
7400
|
name: "on_conflict",
|
|
7265
7401
|
type: "string",
|
|
7266
7402
|
required: false,
|
|
7267
|
-
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7403
|
+
description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
|
|
7268
7404
|
},
|
|
7269
7405
|
{
|
|
7270
7406
|
name: "columns",
|
|
@@ -7316,7 +7452,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7316
7452
|
resource: "database.databases.tables",
|
|
7317
7453
|
method: "create",
|
|
7318
7454
|
summary: "Create table",
|
|
7319
|
-
description:
|
|
7455
|
+
description: 'Creates a table together with its initial fields in one call and returns it (HTTP 201) with generated tbl_ and fld_ ids. name must match ^[a-z_][a-z0-9_]{0,62}$ and be unused in this database (duplicate: 409 UNIQUE_VIOLATION). fields is required and may be an empty array; fields can also be added later with databaseAddField. Limits: 50 tables per database, 64 fields per table, and 16 indexed or unique fields per table; exceeding one returns 400 LIMIT_EXCEEDED. Fields default to indexed:false. Set indexed:true explicitly for fields used in filters or ordering. Only indexed:true or unique:true consumes one of the 16 indexed-or-unique field slots; a field with both consumes one slot. Unique fields still consume a slot even with indexed:false. Existing fields are unchanged. Minimal field example: {"name":"notes","type":"string","indexed":false}. Every row also has a system id column, which is not declared as a field. Insert data afterwards with databaseInsert. Unlike Supabase, define schema with this table API and the field APIs; PostgreSQL DDL and SQL migration files cannot be submitted. Each table supports up to 1,000,000 rows.',
|
|
7320
7456
|
http: "POST",
|
|
7321
7457
|
path: "/database/v1/databases/{database_id}/tables",
|
|
7322
7458
|
streaming: "no",
|
|
@@ -7437,7 +7573,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7437
7573
|
resource: "database.databases.tables.fields",
|
|
7438
7574
|
method: "create",
|
|
7439
7575
|
summary: "Add field",
|
|
7440
|
-
description:
|
|
7576
|
+
description: 'Adds one field to an existing table and returns the updated table (HTTP 201). Required inputs are name (lowercase letters, digits and underscores; id and names starting with _ are reserved) and type (string, integer, number, boolean, datetime, json or link); json needs options.schema and link needs options.linked_table_id and options.multiple. Adding a required field to a table that already has rows needs a default, otherwise the call fails with 400 VALIDATION_FAILED; a default is written into every existing row. Fields default to indexed:false. Set indexed:true explicitly for fields used in filters or ordering. Only indexed:true or unique:true consumes one of the 16 indexed-or-unique field slots; a field with both consumes one slot. Unique fields still consume a slot even with indexed:false. Existing fields are unchanged. Minimal field example: {"name":"notes","type":"string","indexed":false}. JSON and link fields cannot be indexed. Limits: 64 fields and 16 indexed or unique fields per table (400 LIMIT_EXCEEDED). Unlike Supabase, schema evolution uses field definitions rather than ALTER TABLE statements or SQL migrations.',
|
|
7441
7577
|
http: "POST",
|
|
7442
7578
|
path: "/database/v1/databases/{database_id}/tables/{table}/fields",
|
|
7443
7579
|
streaming: "no",
|
|
@@ -7607,7 +7743,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7607
7743
|
resource: "file.files",
|
|
7608
7744
|
method: "create",
|
|
7609
7745
|
summary: "Upload file",
|
|
7610
|
-
description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most
|
|
7746
|
+
description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 100000000 bytes, and only user_data, assistants and vision purposes are accepted. Send file bytes as a multipart file part, not a filename or file ID; in the SDK use a File or Blob, for example new File(["Return within 23 days."], "policy.txt", { type: "text/plain" }). Content determines the MIME type. Supported uploads include PDF, DOCX/XLSX/PPTX, PNG/JPEG/GIF/WebP, MP3/WAV/FLAC/OGG/M4A, MP4/WebM, and UTF-8 JSON/NDJSON/CSV/Markdown/plain text; empty, unsupported, oversized files and unsupported purposes return 400. Use Uploads for larger files. The purpose vision accepts only PNG, JPEG, GIF and WebP, while conversation images require user_data. The returned ID belongs to your tenant; upload alone does not ingest the file into Knowledge. Knowledge attachment has a lower limit of 100000000 bytes. Optionally set expires_after[anchor]=created_at with expires_after[seconds] (3600–2592000), or praxis[expires_in_seconds] (3600–7776000), never both. Without expiry, the file persists until deleted.',
|
|
7611
7747
|
http: "POST",
|
|
7612
7748
|
path: "/file/v1/files",
|
|
7613
7749
|
streaming: "no",
|
|
@@ -7622,7 +7758,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7622
7758
|
name: "file",
|
|
7623
7759
|
type: "string",
|
|
7624
7760
|
required: true,
|
|
7625
|
-
description: "File bytes in one multipart file part, not a filename or file ID. The file must be nonempty and at most
|
|
7761
|
+
description: "File bytes in one multipart file part, not a filename or file ID. The file must be nonempty and at most 100000000 bytes; its content determines the MIME type."
|
|
7626
7762
|
},
|
|
7627
7763
|
{
|
|
7628
7764
|
name: "purpose",
|
|
@@ -7671,7 +7807,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7671
7807
|
resource: "file.files",
|
|
7672
7808
|
method: "retrieve",
|
|
7673
7809
|
summary: "Retrieve file",
|
|
7674
|
-
description: "Retrieve metadata for a live file owned by your tenant. Use its
|
|
7810
|
+
description: "Retrieve metadata for a live file owned by your tenant. Use its file- ID from upload or list. Missing, deleted, expired and other-tenant files return 404; use the content endpoint to download the bytes.",
|
|
7675
7811
|
http: "GET",
|
|
7676
7812
|
path: "/file/v1/files/{file_id}",
|
|
7677
7813
|
streaming: "no",
|
|
@@ -7688,7 +7824,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7688
7824
|
resource: "file.files",
|
|
7689
7825
|
method: "retrieveContent",
|
|
7690
7826
|
summary: "Retrieve file content",
|
|
7691
|
-
description: "Download the original bytes of a live file owned by your tenant. Supply its
|
|
7827
|
+
description: "Download the original bytes of a live file owned by your tenant. Supply its file- ID from upload or list. A single byte Range can return a partial response; a range outside the file returns 416. Missing, deleted, expired and other-tenant files return 404.",
|
|
7692
7828
|
http: "GET",
|
|
7693
7829
|
path: "/file/v1/files/{file_id}/content",
|
|
7694
7830
|
streaming: "no",
|
|
@@ -7701,6 +7837,152 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
|
|
|
7701
7837
|
],
|
|
7702
7838
|
query: []
|
|
7703
7839
|
},
|
|
7840
|
+
{
|
|
7841
|
+
resource: "file.uploads",
|
|
7842
|
+
method: "create",
|
|
7843
|
+
summary: "Create an upload",
|
|
7844
|
+
description: "Start a multipart upload for a file larger than the 100000000-byte direct-upload limit. Supply the exact byte length, filename, MIME type and purpose. Unlike OpenAI, only user_data, assistants and vision are accepted. The API accepts up to 8000000000 bytes; the Console and SDK uploadFile helper cap files at 2 GiB. Add parts of at most 64000000 bytes and complete within one hour. Optional part_size enables fixed-size, retryable parts. expires_after applies to the resulting file (3600–7776000 seconds on this own face); without it the file persists until deleted.",
|
|
7845
|
+
http: "POST",
|
|
7846
|
+
path: "/file/v1/uploads",
|
|
7847
|
+
streaming: "no",
|
|
7848
|
+
pagination: false,
|
|
7849
|
+
pathParams: [],
|
|
7850
|
+
query: [],
|
|
7851
|
+
body: {
|
|
7852
|
+
required: true,
|
|
7853
|
+
fields: [
|
|
7854
|
+
{
|
|
7855
|
+
name: "bytes",
|
|
7856
|
+
type: "integer",
|
|
7857
|
+
required: true,
|
|
7858
|
+
description: "Exact complete file length in bytes, from 1 through 8000000000; the sum of completed parts must match."
|
|
7859
|
+
},
|
|
7860
|
+
{
|
|
7861
|
+
name: "filename",
|
|
7862
|
+
type: "string",
|
|
7863
|
+
required: true,
|
|
7864
|
+
description: "Filename for the resulting file, at most 255 UTF-8 bytes."
|
|
7865
|
+
},
|
|
7866
|
+
{
|
|
7867
|
+
name: "mime_type",
|
|
7868
|
+
type: "string",
|
|
7869
|
+
required: true,
|
|
7870
|
+
description: "Declared MIME type; validated against the assembled content."
|
|
7871
|
+
},
|
|
7872
|
+
{
|
|
7873
|
+
name: "purpose",
|
|
7874
|
+
type: "string",
|
|
7875
|
+
enum: [
|
|
7876
|
+
"user_data",
|
|
7877
|
+
"assistants",
|
|
7878
|
+
"vision"
|
|
7879
|
+
],
|
|
7880
|
+
required: true,
|
|
7881
|
+
description: "Use user_data for conversation attachments, assistants for assistant files, or vision for PNG, JPEG, GIF and WebP images."
|
|
7882
|
+
},
|
|
7883
|
+
{
|
|
7884
|
+
name: "expires_after",
|
|
7885
|
+
type: "object",
|
|
7886
|
+
required: false,
|
|
7887
|
+
description: "Optional expiry policy for the resulting file; omission retains the file until deletion."
|
|
7888
|
+
},
|
|
7889
|
+
{
|
|
7890
|
+
name: "part_size",
|
|
7891
|
+
type: "integer",
|
|
7892
|
+
required: false,
|
|
7893
|
+
description: "Optional fixed part size in bytes, 5242880–64000000. Requires part_number on every part; retries of identical bytes at the same number return the same part. Omit to use arbitrary-sized parts."
|
|
7894
|
+
}
|
|
7895
|
+
]
|
|
7896
|
+
}
|
|
7897
|
+
},
|
|
7898
|
+
{
|
|
7899
|
+
resource: "file.uploads",
|
|
7900
|
+
method: "cancel",
|
|
7901
|
+
summary: "Cancel an upload",
|
|
7902
|
+
description: "Cancel an unfinished upload using upload_id from create and release its reserved storage. Further parts and completion are rejected. Cancelling an already cancelled upload returns the same terminal result; a completed upload cannot be cancelled. Delete its resulting file instead.",
|
|
7903
|
+
http: "POST",
|
|
7904
|
+
path: "/file/v1/uploads/{upload_id}/cancel",
|
|
7905
|
+
streaming: "no",
|
|
7906
|
+
pagination: false,
|
|
7907
|
+
pathParams: [
|
|
7908
|
+
{
|
|
7909
|
+
name: "upload_id",
|
|
7910
|
+
sdkName: "upload_id"
|
|
7911
|
+
}
|
|
7912
|
+
],
|
|
7913
|
+
query: []
|
|
7914
|
+
},
|
|
7915
|
+
{
|
|
7916
|
+
resource: "file.uploads",
|
|
7917
|
+
method: "complete",
|
|
7918
|
+
summary: "Complete an upload",
|
|
7919
|
+
description: "Assemble the uploaded parts into a file. Supply upload_id from create and part_ids from addPart in file byte order; their sizes must total the declared bytes. Optional md5 verifies the assembled content. Retrying identical part_ids and normalized md5 returns the same result; different inputs return 409. Unlike OpenAI, completed can contain a file still processing (status uploaded). Poll files.retrieve using file.id until status processed (own face state active); error, expiry or 404 means processing failed and the file cannot be used.",
|
|
7920
|
+
http: "POST",
|
|
7921
|
+
path: "/file/v1/uploads/{upload_id}/complete",
|
|
7922
|
+
streaming: "no",
|
|
7923
|
+
pagination: false,
|
|
7924
|
+
pathParams: [
|
|
7925
|
+
{
|
|
7926
|
+
name: "upload_id",
|
|
7927
|
+
sdkName: "upload_id"
|
|
7928
|
+
}
|
|
7929
|
+
],
|
|
7930
|
+
query: [],
|
|
7931
|
+
body: {
|
|
7932
|
+
required: true,
|
|
7933
|
+
fields: [
|
|
7934
|
+
{
|
|
7935
|
+
name: "part_ids",
|
|
7936
|
+
type: "array",
|
|
7937
|
+
itemType: "string",
|
|
7938
|
+
required: true,
|
|
7939
|
+
description: "All part IDs in concatenation order, without duplicates. Fixed-size uploads require increasing part_number order."
|
|
7940
|
+
},
|
|
7941
|
+
{
|
|
7942
|
+
name: "md5",
|
|
7943
|
+
type: "string",
|
|
7944
|
+
required: false,
|
|
7945
|
+
description: "Optional whole-file MD5 as 32 hexadecimal characters; verified after assembly."
|
|
7946
|
+
}
|
|
7947
|
+
]
|
|
7948
|
+
}
|
|
7949
|
+
},
|
|
7950
|
+
{
|
|
7951
|
+
resource: "file.uploads.parts",
|
|
7952
|
+
method: "create",
|
|
7953
|
+
summary: "Add an upload part",
|
|
7954
|
+
description: "Send one nonempty part as the multipart data field, at most 64000000 bytes. Parts may arrive concurrently in any order. Use upload_id from create. For a fixed-size upload, supply part_number starting at 1 and exactly part_size bytes except for the final remainder; retry the same number with identical bytes to recover its part ID. Without part_size, each request creates a new part and part_number is ignored. Save the returned part IDs for complete.",
|
|
7955
|
+
http: "POST",
|
|
7956
|
+
path: "/file/v1/uploads/{upload_id}/parts",
|
|
7957
|
+
streaming: "no",
|
|
7958
|
+
pagination: false,
|
|
7959
|
+
multipart: true,
|
|
7960
|
+
pathParams: [
|
|
7961
|
+
{
|
|
7962
|
+
name: "upload_id",
|
|
7963
|
+
sdkName: "upload_id"
|
|
7964
|
+
}
|
|
7965
|
+
],
|
|
7966
|
+
query: [
|
|
7967
|
+
{
|
|
7968
|
+
name: "part_number",
|
|
7969
|
+
type: "integer",
|
|
7970
|
+
required: false,
|
|
7971
|
+
description: "Required when create set part_size; 1 through ceil(bytes / part_size). Ignored for general uploads."
|
|
7972
|
+
}
|
|
7973
|
+
],
|
|
7974
|
+
body: {
|
|
7975
|
+
required: true,
|
|
7976
|
+
fields: [
|
|
7977
|
+
{
|
|
7978
|
+
name: "data",
|
|
7979
|
+
type: "string",
|
|
7980
|
+
required: true,
|
|
7981
|
+
description: "Raw bytes of this part, nonempty and at most 64000000 bytes."
|
|
7982
|
+
}
|
|
7983
|
+
]
|
|
7984
|
+
}
|
|
7985
|
+
},
|
|
7704
7986
|
{
|
|
7705
7987
|
resource: "knowledge.vectorStores",
|
|
7706
7988
|
method: "list",
|
|
@@ -14607,32 +14889,258 @@ for more details.`
|
|
|
14607
14889
|
}
|
|
14608
14890
|
];
|
|
14609
14891
|
|
|
14610
|
-
// ../../packages/sdk/typescript/src/core/
|
|
14611
|
-
function
|
|
14612
|
-
const
|
|
14613
|
-
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
|
|
14620
|
-
|
|
14621
|
-
|
|
14622
|
-
|
|
14623
|
-
|
|
14624
|
-
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
|
|
14630
|
-
|
|
14892
|
+
// ../../packages/sdk/typescript/src/core/errors.ts
|
|
14893
|
+
function problemFrom(status, headers, body, statusText) {
|
|
14894
|
+
const value = body && typeof body === "object" ? body : {};
|
|
14895
|
+
const nested = value.error && typeof value.error === "object" ? value.error : {};
|
|
14896
|
+
const string = (v) => typeof v === "string" && v.trim() ? v : undefined;
|
|
14897
|
+
const fallback = statusText || { 400: "Bad Request", 401: "Unauthorized", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 408: "Request Timeout", 409: "Conflict", 413: "Payload Too Large", 415: "Unsupported Media Type", 422: "Unprocessable Entity", 429: "Too Many Requests", 500: "Internal Server Error", 502: "Bad Gateway", 503: "Service Unavailable", 504: "Gateway Timeout" }[status] || `HTTP ${status}`;
|
|
14898
|
+
const detail = string(value.detail) ?? string(nested.message) ?? string(value.message) ?? string(body);
|
|
14899
|
+
const title = string(value.title) ?? fallback;
|
|
14900
|
+
const param = nested.param ?? value.param;
|
|
14901
|
+
return {
|
|
14902
|
+
status,
|
|
14903
|
+
message: detail ?? title,
|
|
14904
|
+
title,
|
|
14905
|
+
detail,
|
|
14906
|
+
code: string(value.code) ?? string(nested.code) ?? string(nested.type) ?? string(value.error_code),
|
|
14907
|
+
type: string(nested.type) ?? string(value.type),
|
|
14908
|
+
param: typeof param === "string" ? param : param === null || nested.param === null ? null : undefined,
|
|
14909
|
+
errors: Array.isArray(value.errors) ? value.errors : [],
|
|
14910
|
+
requestId: headers.get("x-request-id") ?? string(value.requestId) ?? string(value.request_id),
|
|
14911
|
+
raw: body
|
|
14912
|
+
};
|
|
14631
14913
|
}
|
|
14632
14914
|
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14915
|
+
class PraxisError extends Error {
|
|
14916
|
+
status;
|
|
14917
|
+
code;
|
|
14918
|
+
type;
|
|
14919
|
+
title;
|
|
14920
|
+
detail;
|
|
14921
|
+
errors;
|
|
14922
|
+
requestId;
|
|
14923
|
+
param;
|
|
14924
|
+
raw;
|
|
14925
|
+
constructor(problem = {}, options) {
|
|
14926
|
+
super(problem.message ?? problem.detail ?? problem.title ?? `Praxis request failed${problem.status ? ` (${problem.status})` : ""}`, options);
|
|
14927
|
+
this.name = "PraxisError";
|
|
14928
|
+
this.status = problem.status;
|
|
14929
|
+
this.code = problem.code;
|
|
14930
|
+
this.type = problem.type;
|
|
14931
|
+
this.title = problem.title;
|
|
14932
|
+
this.detail = problem.detail;
|
|
14933
|
+
this.errors = problem.errors ?? [];
|
|
14934
|
+
this.requestId = problem.requestId;
|
|
14935
|
+
this.param = problem.param;
|
|
14936
|
+
this.raw = problem.raw;
|
|
14937
|
+
}
|
|
14938
|
+
static fromResponse(response, body) {
|
|
14939
|
+
return new PraxisError(problemFrom(response.status, response.headers, body, response.statusText));
|
|
14940
|
+
}
|
|
14941
|
+
}
|
|
14942
|
+
|
|
14943
|
+
class PraxisConnectionError extends PraxisError {
|
|
14944
|
+
constructor(cause) {
|
|
14945
|
+
super({ code: "CONNECTION_ERROR", title: "Unable to connect to Praxis" }, { cause });
|
|
14946
|
+
this.name = "PraxisConnectionError";
|
|
14947
|
+
}
|
|
14948
|
+
}
|
|
14949
|
+
|
|
14950
|
+
class PraxisTimeoutError extends PraxisError {
|
|
14951
|
+
constructor(timeoutMs) {
|
|
14952
|
+
super({ code: "TIMEOUT", title: `Praxis request exceeded ${timeoutMs} ms` });
|
|
14953
|
+
this.name = "PraxisTimeoutError";
|
|
14954
|
+
}
|
|
14955
|
+
}
|
|
14956
|
+
|
|
14957
|
+
// ../../packages/sdk/typescript/src/core/retry.ts
|
|
14958
|
+
function canRetry(request) {
|
|
14959
|
+
return request.method !== "POST" || Boolean(request.headers.get("Idempotency-Key")?.trim());
|
|
14960
|
+
}
|
|
14961
|
+
function retryAfterMs(value, now = Date.now()) {
|
|
14962
|
+
if (!value)
|
|
14963
|
+
return;
|
|
14964
|
+
if (/^\d+(?:\.\d+)?$/.test(value.trim()))
|
|
14965
|
+
return Number(value) * 1000;
|
|
14966
|
+
const date = Date.parse(value);
|
|
14967
|
+
return Number.isFinite(date) ? Math.max(0, date - now) : undefined;
|
|
14968
|
+
}
|
|
14969
|
+
function retryDelay(attempt, retryAfter, random = Math.random) {
|
|
14970
|
+
return retryAfterMs(retryAfter) ?? Math.min(30000, 500 * 2 ** attempt) * (0.5 + random() * 0.5);
|
|
14971
|
+
}
|
|
14972
|
+
function abortable(promise, signal) {
|
|
14973
|
+
signal.throwIfAborted();
|
|
14974
|
+
return new Promise((resolve, reject) => {
|
|
14975
|
+
const abort = () => reject(signal.reason);
|
|
14976
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
14977
|
+
promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
14978
|
+
});
|
|
14979
|
+
}
|
|
14980
|
+
function sleep(ms, signal) {
|
|
14981
|
+
signal.throwIfAborted();
|
|
14982
|
+
return new Promise((resolve, reject) => {
|
|
14983
|
+
const abort = () => {
|
|
14984
|
+
clearTimeout(timer);
|
|
14985
|
+
reject(signal.reason);
|
|
14986
|
+
};
|
|
14987
|
+
const timer = setTimeout(() => {
|
|
14988
|
+
signal.removeEventListener("abort", abort);
|
|
14989
|
+
resolve();
|
|
14990
|
+
}, ms);
|
|
14991
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
14992
|
+
});
|
|
14993
|
+
}
|
|
14994
|
+
async function fetchWithRetry(request, fetcher, options) {
|
|
14995
|
+
const eligible = canRetry(request);
|
|
14996
|
+
const wait = options.wait ?? sleep;
|
|
14997
|
+
for (let attempt = 0;; attempt++) {
|
|
14998
|
+
options.signal.throwIfAborted();
|
|
14999
|
+
let response;
|
|
15000
|
+
try {
|
|
15001
|
+
response = await abortable(fetcher(request.clone()), options.signal);
|
|
15002
|
+
} catch (cause) {
|
|
15003
|
+
options.signal.throwIfAborted();
|
|
15004
|
+
if (!eligible || attempt >= options.maxRetries)
|
|
15005
|
+
throw new PraxisConnectionError(cause);
|
|
15006
|
+
await wait(retryDelay(attempt, null, options.random), options.signal);
|
|
15007
|
+
continue;
|
|
15008
|
+
}
|
|
15009
|
+
const retriable = response.status === 408 || response.status === 429 || response.status >= 500 && response.status <= 599;
|
|
15010
|
+
if (!eligible || !retriable || attempt >= options.maxRetries)
|
|
15011
|
+
return response;
|
|
15012
|
+
const delay = retryDelay(attempt, response.headers.get("Retry-After"), options.random);
|
|
15013
|
+
await response.body?.cancel();
|
|
15014
|
+
await wait(delay, options.signal);
|
|
15015
|
+
}
|
|
15016
|
+
}
|
|
15017
|
+
|
|
15018
|
+
// ../../packages/sdk/typescript/src/helpers/file-upload.ts
|
|
15019
|
+
var MAX_RETRIES = 5;
|
|
15020
|
+
function retryable(error) {
|
|
15021
|
+
return error instanceof PraxisConnectionError || error instanceof PraxisTimeoutError || error instanceof SyntaxError || error instanceof PraxisError && (error.status === 408 || error.status === 429 || error.status !== undefined && error.status >= 500 && error.status <= 599);
|
|
15022
|
+
}
|
|
15023
|
+
async function retry(signal, operation) {
|
|
15024
|
+
for (let used = 0;; used++) {
|
|
15025
|
+
signal.throwIfAborted();
|
|
15026
|
+
try {
|
|
15027
|
+
return await operation();
|
|
15028
|
+
} catch (error) {
|
|
15029
|
+
signal.throwIfAborted();
|
|
15030
|
+
if (used >= MAX_RETRIES || !retryable(error))
|
|
15031
|
+
throw error;
|
|
15032
|
+
await sleep(500 * 2 ** used, signal);
|
|
15033
|
+
}
|
|
15034
|
+
}
|
|
15035
|
+
}
|
|
15036
|
+
async function uploadFile(client, file, options) {
|
|
15037
|
+
options.signal?.throwIfAborted();
|
|
15038
|
+
if (file.size < 1 || file.size > 2 * 1024 ** 3)
|
|
15039
|
+
throw new RangeError("File size must be 1 byte through 2 GiB");
|
|
15040
|
+
const partSize = options.partSize ?? 50 * 1024 ** 2;
|
|
15041
|
+
const concurrency = options.concurrency ?? 3;
|
|
15042
|
+
if (!Number.isSafeInteger(partSize) || partSize < 5 * 1024 ** 2 || partSize > 64000000)
|
|
15043
|
+
throw new RangeError("partSize must be an integer from 5242880 through 64000000");
|
|
15044
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1)
|
|
15045
|
+
throw new RangeError("concurrency must be a positive integer");
|
|
15046
|
+
const filename = options.filename ?? (typeof File !== "undefined" && file instanceof File ? file.name : "upload");
|
|
15047
|
+
const work = new AbortController;
|
|
15048
|
+
const abort = () => work.abort(options.signal?.reason);
|
|
15049
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
15050
|
+
const signal = work.signal;
|
|
15051
|
+
const request = { signal, maxRetries: 0, timeoutMs: 120000 };
|
|
15052
|
+
let uploadId;
|
|
15053
|
+
const active = async (initial) => {
|
|
15054
|
+
let result = initial;
|
|
15055
|
+
for (let polls = 0;; polls++) {
|
|
15056
|
+
signal.throwIfAborted();
|
|
15057
|
+
if (result.state === "active")
|
|
15058
|
+
return result;
|
|
15059
|
+
if (result.state !== "processing")
|
|
15060
|
+
throw new PraxisError({ code: "FILE_PROCESSING_FAILED", message: `File ${result.id} is not active (${result.state})` });
|
|
15061
|
+
await sleep(Math.min(5000, 1000 * 2 ** polls), signal);
|
|
15062
|
+
result = await retry(signal, () => client.file.files.retrieve({ path: { file_id: result.id }, ...request }));
|
|
15063
|
+
}
|
|
15064
|
+
};
|
|
15065
|
+
try {
|
|
15066
|
+
signal.throwIfAborted();
|
|
15067
|
+
options.onProgress?.(0);
|
|
15068
|
+
if (file.size <= 32 * 1024 ** 2) {
|
|
15069
|
+
const result2 = await client.file.files.create({ body: { file: new File([file], filename, { type: file.type }), purpose: options.purpose }, ...request });
|
|
15070
|
+
options.onProgress?.(1);
|
|
15071
|
+
return await active(result2);
|
|
15072
|
+
}
|
|
15073
|
+
const upload = await client.file.uploads.create({ body: { bytes: file.size, filename, mime_type: file.type || "application/octet-stream", purpose: options.purpose, part_size: partSize }, ...request });
|
|
15074
|
+
uploadId = upload.id;
|
|
15075
|
+
signal.throwIfAborted();
|
|
15076
|
+
const path = { upload_id: uploadId };
|
|
15077
|
+
const count = Math.ceil(file.size / partSize);
|
|
15078
|
+
const ids = new Array(count);
|
|
15079
|
+
let cursor = 0, confirmed = 0;
|
|
15080
|
+
const worker = async () => {
|
|
15081
|
+
while (cursor < count) {
|
|
15082
|
+
signal.throwIfAborted();
|
|
15083
|
+
const index = cursor++;
|
|
15084
|
+
const chunk = file.slice(index * partSize, Math.min(file.size, (index + 1) * partSize));
|
|
15085
|
+
const part = await retry(signal, () => client.file.uploads.parts.create({ path, query: { part_number: index + 1 }, body: { data: new File([chunk], filename) }, ...request }));
|
|
15086
|
+
ids[index] = part.id;
|
|
15087
|
+
confirmed += chunk.size;
|
|
15088
|
+
options.onProgress?.(confirmed / file.size);
|
|
15089
|
+
}
|
|
15090
|
+
};
|
|
15091
|
+
const workers = Array.from({ length: Math.min(concurrency, count) }, worker);
|
|
15092
|
+
try {
|
|
15093
|
+
await Promise.all(workers);
|
|
15094
|
+
} catch (error) {
|
|
15095
|
+
work.abort();
|
|
15096
|
+
await Promise.allSettled(workers);
|
|
15097
|
+
throw error;
|
|
15098
|
+
}
|
|
15099
|
+
const result = await retry(signal, () => client.file.uploads.complete({ path, body: { part_ids: ids }, ...request }));
|
|
15100
|
+
if (result.error)
|
|
15101
|
+
throw new PraxisError({ code: result.error.code, message: result.error.message });
|
|
15102
|
+
if (result.status !== "completed" || !result.file)
|
|
15103
|
+
throw new PraxisError({ code: "INVALID_RESPONSE", message: "Complete did not return a completed Upload with a file" });
|
|
15104
|
+
return await active(result.file);
|
|
15105
|
+
} catch (error) {
|
|
15106
|
+
work.abort();
|
|
15107
|
+
if (uploadId) {
|
|
15108
|
+
await client.file.uploads.cancel({ path: { upload_id: uploadId }, maxRetries: 0, timeoutMs: 1e4 }).catch(() => {});
|
|
15109
|
+
}
|
|
15110
|
+
if (options.signal?.aborted)
|
|
15111
|
+
throw options.signal.reason;
|
|
15112
|
+
throw error;
|
|
15113
|
+
} finally {
|
|
15114
|
+
options.signal?.removeEventListener("abort", abort);
|
|
15115
|
+
}
|
|
15116
|
+
}
|
|
15117
|
+
|
|
15118
|
+
// ../../packages/sdk/typescript/src/core/multipart.ts
|
|
15119
|
+
function multipartBodySerializer(body) {
|
|
15120
|
+
const data = new FormData;
|
|
15121
|
+
function append(key, value) {
|
|
15122
|
+
if (value === undefined || value === null)
|
|
15123
|
+
return;
|
|
15124
|
+
if (value instanceof Blob) {
|
|
15125
|
+
data.append(key, value);
|
|
15126
|
+
} else if (Array.isArray(value)) {
|
|
15127
|
+
for (const item of value)
|
|
15128
|
+
append(key, item);
|
|
15129
|
+
} else if (typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) {
|
|
15130
|
+
for (const [subkey, item] of Object.entries(value))
|
|
15131
|
+
append(`${key}[${subkey}]`, item);
|
|
15132
|
+
} else {
|
|
15133
|
+
data.append(key, String(value));
|
|
15134
|
+
}
|
|
15135
|
+
}
|
|
15136
|
+
for (const [key, value] of Object.entries(body ?? {}))
|
|
15137
|
+
append(key, value);
|
|
15138
|
+
return data;
|
|
15139
|
+
}
|
|
15140
|
+
|
|
15141
|
+
// ../../packages/sdk/typescript/src/generated/core/bodySerializer.gen.ts
|
|
15142
|
+
var serializeFormDataPair = (data, key, value) => {
|
|
15143
|
+
if (typeof value === "string" || value instanceof Blob) {
|
|
14636
15144
|
data.append(key, value);
|
|
14637
15145
|
} else if (value instanceof Date) {
|
|
14638
15146
|
data.append(key, value.toISOString());
|
|
@@ -14674,9 +15182,9 @@ function createSseClient({
|
|
|
14674
15182
|
...options
|
|
14675
15183
|
}) {
|
|
14676
15184
|
let lastEventId;
|
|
14677
|
-
const
|
|
15185
|
+
const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
14678
15186
|
const createStream = async function* () {
|
|
14679
|
-
let
|
|
15187
|
+
let retryDelay2 = sseDefaultRetryDelay ?? 3000;
|
|
14680
15188
|
let attempt = 0;
|
|
14681
15189
|
const signal = options.signal ?? new AbortController().signal;
|
|
14682
15190
|
while (true) {
|
|
@@ -14740,7 +15248,7 @@ function createSseClient({
|
|
|
14740
15248
|
} else if (line.startsWith("retry:")) {
|
|
14741
15249
|
const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
|
|
14742
15250
|
if (!Number.isNaN(parsed)) {
|
|
14743
|
-
|
|
15251
|
+
retryDelay2 = parsed;
|
|
14744
15252
|
}
|
|
14745
15253
|
}
|
|
14746
15254
|
}
|
|
@@ -14768,7 +15276,7 @@ function createSseClient({
|
|
|
14768
15276
|
data,
|
|
14769
15277
|
event: eventName,
|
|
14770
15278
|
id: lastEventId,
|
|
14771
|
-
retry:
|
|
15279
|
+
retry: retryDelay2
|
|
14772
15280
|
});
|
|
14773
15281
|
if (dataLines.length) {
|
|
14774
15282
|
yield data;
|
|
@@ -14785,8 +15293,8 @@ function createSseClient({
|
|
|
14785
15293
|
if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) {
|
|
14786
15294
|
break;
|
|
14787
15295
|
}
|
|
14788
|
-
const backoff = Math.min(
|
|
14789
|
-
await
|
|
15296
|
+
const backoff = Math.min(retryDelay2 * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
|
|
15297
|
+
await sleep2(backoff);
|
|
14790
15298
|
}
|
|
14791
15299
|
}
|
|
14792
15300
|
};
|
|
@@ -15429,6 +15937,19 @@ var createClient = (config = {}) => {
|
|
|
15429
15937
|
var client = createClient(createConfig({ baseUrl: "https://api.deepraxis.com" }));
|
|
15430
15938
|
|
|
15431
15939
|
// ../../packages/sdk/typescript/src/generated/sdk.gen.ts
|
|
15940
|
+
var unarchiveAgent = (options) => (options.client ?? client).post({
|
|
15941
|
+
security: [{
|
|
15942
|
+
key: "BearerAuth",
|
|
15943
|
+
scheme: "bearer",
|
|
15944
|
+
type: "http"
|
|
15945
|
+
}, {
|
|
15946
|
+
key: "ApiKeyAuth",
|
|
15947
|
+
name: "X-API-Key",
|
|
15948
|
+
type: "apiKey"
|
|
15949
|
+
}],
|
|
15950
|
+
url: "/agent/v1/agents/{agent_id}/unarchive",
|
|
15951
|
+
...options
|
|
15952
|
+
});
|
|
15432
15953
|
var deleteRunFeedback = (options) => (options.client ?? client).delete({
|
|
15433
15954
|
security: [{
|
|
15434
15955
|
key: "BearerAuth",
|
|
@@ -15750,7 +16271,11 @@ var connectComputer = (options) => (options.client ?? client).post({
|
|
|
15750
16271
|
type: "apiKey"
|
|
15751
16272
|
}],
|
|
15752
16273
|
url: "/agent/v1/computers/{computer_id}/connect",
|
|
15753
|
-
...options
|
|
16274
|
+
...options,
|
|
16275
|
+
headers: {
|
|
16276
|
+
"Content-Type": "application/json",
|
|
16277
|
+
...options.headers
|
|
16278
|
+
}
|
|
15754
16279
|
});
|
|
15755
16280
|
var renewComputerLease = (options) => (options.client ?? client).post({
|
|
15756
16281
|
security: [{
|
|
@@ -16193,6 +16718,55 @@ var fileRetrieveFileContent = (options) => (options.client ?? client).get({
|
|
|
16193
16718
|
url: "/file/v1/files/{file_id}/content",
|
|
16194
16719
|
...options
|
|
16195
16720
|
});
|
|
16721
|
+
var fileCreateUpload = (options) => (options.client ?? client).post({
|
|
16722
|
+
security: [{
|
|
16723
|
+
key: "BearerAuth",
|
|
16724
|
+
scheme: "bearer",
|
|
16725
|
+
type: "http"
|
|
16726
|
+
}],
|
|
16727
|
+
url: "/file/v1/uploads",
|
|
16728
|
+
...options,
|
|
16729
|
+
headers: {
|
|
16730
|
+
"Content-Type": "application/json",
|
|
16731
|
+
...options.headers
|
|
16732
|
+
}
|
|
16733
|
+
});
|
|
16734
|
+
var fileAddUploadPart = (options) => (options.client ?? client).post({
|
|
16735
|
+
...formDataBodySerializer,
|
|
16736
|
+
security: [{
|
|
16737
|
+
key: "BearerAuth",
|
|
16738
|
+
scheme: "bearer",
|
|
16739
|
+
type: "http"
|
|
16740
|
+
}],
|
|
16741
|
+
url: "/file/v1/uploads/{upload_id}/parts",
|
|
16742
|
+
...options,
|
|
16743
|
+
headers: {
|
|
16744
|
+
"Content-Type": null,
|
|
16745
|
+
...options.headers
|
|
16746
|
+
}
|
|
16747
|
+
});
|
|
16748
|
+
var fileCompleteUpload = (options) => (options.client ?? client).post({
|
|
16749
|
+
security: [{
|
|
16750
|
+
key: "BearerAuth",
|
|
16751
|
+
scheme: "bearer",
|
|
16752
|
+
type: "http"
|
|
16753
|
+
}],
|
|
16754
|
+
url: "/file/v1/uploads/{upload_id}/complete",
|
|
16755
|
+
...options,
|
|
16756
|
+
headers: {
|
|
16757
|
+
"Content-Type": "application/json",
|
|
16758
|
+
...options.headers
|
|
16759
|
+
}
|
|
16760
|
+
});
|
|
16761
|
+
var fileCancelUpload = (options) => (options.client ?? client).post({
|
|
16762
|
+
security: [{
|
|
16763
|
+
key: "BearerAuth",
|
|
16764
|
+
scheme: "bearer",
|
|
16765
|
+
type: "http"
|
|
16766
|
+
}],
|
|
16767
|
+
url: "/file/v1/uploads/{upload_id}/cancel",
|
|
16768
|
+
...options
|
|
16769
|
+
});
|
|
16196
16770
|
var healthCheck = (options) => (options?.client ?? client).get({ url: "/meta/v1/health", ...options });
|
|
16197
16771
|
var metaMethodsSearch = (options) => (options?.client ?? client).get({ url: "/meta/v1/methods", ...options });
|
|
16198
16772
|
var metaMethodsRetrieve = (options) => (options.client ?? client).get({ url: "/meta/v1/methods/{name}", ...options });
|
|
@@ -17028,7 +17602,7 @@ var runSandboxCommand = (options) => (options.client ?? client).post({
|
|
|
17028
17602
|
...options.headers
|
|
17029
17603
|
}
|
|
17030
17604
|
});
|
|
17031
|
-
var
|
|
17605
|
+
var sessionsDelete = (options) => (options.client ?? client).delete({
|
|
17032
17606
|
security: [{
|
|
17033
17607
|
key: "BearerAuth",
|
|
17034
17608
|
scheme: "bearer",
|
|
@@ -17038,10 +17612,10 @@ var agentsList = (options) => (options?.client ?? client).get({
|
|
|
17038
17612
|
name: "X-API-Key",
|
|
17039
17613
|
type: "apiKey"
|
|
17040
17614
|
}],
|
|
17041
|
-
url: "/agent/v1/
|
|
17615
|
+
url: "/agent/v1/sessions/{session_id}",
|
|
17042
17616
|
...options
|
|
17043
17617
|
});
|
|
17044
|
-
var
|
|
17618
|
+
var sessionsRetrieve = (options) => (options.client ?? client).get({
|
|
17045
17619
|
security: [{
|
|
17046
17620
|
key: "BearerAuth",
|
|
17047
17621
|
scheme: "bearer",
|
|
@@ -17051,14 +17625,27 @@ var agentsCreate = (options) => (options.client ?? client).post({
|
|
|
17051
17625
|
name: "X-API-Key",
|
|
17052
17626
|
type: "apiKey"
|
|
17053
17627
|
}],
|
|
17054
|
-
url: "/agent/v1/
|
|
17628
|
+
url: "/agent/v1/sessions/{session_id}",
|
|
17629
|
+
...options
|
|
17630
|
+
});
|
|
17631
|
+
var sessionsUpdate = (options) => (options.client ?? client).post({
|
|
17632
|
+
security: [{
|
|
17633
|
+
key: "BearerAuth",
|
|
17634
|
+
scheme: "bearer",
|
|
17635
|
+
type: "http"
|
|
17636
|
+
}, {
|
|
17637
|
+
key: "ApiKeyAuth",
|
|
17638
|
+
name: "X-API-Key",
|
|
17639
|
+
type: "apiKey"
|
|
17640
|
+
}],
|
|
17641
|
+
url: "/agent/v1/sessions/{session_id}",
|
|
17055
17642
|
...options,
|
|
17056
17643
|
headers: {
|
|
17057
17644
|
"Content-Type": "application/json",
|
|
17058
17645
|
...options.headers
|
|
17059
17646
|
}
|
|
17060
17647
|
});
|
|
17061
|
-
var
|
|
17648
|
+
var agentsList = (options) => (options?.client ?? client).get({
|
|
17062
17649
|
security: [{
|
|
17063
17650
|
key: "BearerAuth",
|
|
17064
17651
|
scheme: "bearer",
|
|
@@ -17068,10 +17655,10 @@ var agentsRetrieve = (options) => (options.client ?? client).get({
|
|
|
17068
17655
|
name: "X-API-Key",
|
|
17069
17656
|
type: "apiKey"
|
|
17070
17657
|
}],
|
|
17071
|
-
url: "/agent/v1/agents
|
|
17658
|
+
url: "/agent/v1/agents",
|
|
17072
17659
|
...options
|
|
17073
17660
|
});
|
|
17074
|
-
var
|
|
17661
|
+
var agentsCreate = (options) => (options.client ?? client).post({
|
|
17075
17662
|
security: [{
|
|
17076
17663
|
key: "BearerAuth",
|
|
17077
17664
|
scheme: "bearer",
|
|
@@ -17081,14 +17668,14 @@ var agentsUpdate = (options) => (options.client ?? client).post({
|
|
|
17081
17668
|
name: "X-API-Key",
|
|
17082
17669
|
type: "apiKey"
|
|
17083
17670
|
}],
|
|
17084
|
-
url: "/agent/v1/agents
|
|
17671
|
+
url: "/agent/v1/agents",
|
|
17085
17672
|
...options,
|
|
17086
17673
|
headers: {
|
|
17087
17674
|
"Content-Type": "application/json",
|
|
17088
17675
|
...options.headers
|
|
17089
17676
|
}
|
|
17090
17677
|
});
|
|
17091
|
-
var
|
|
17678
|
+
var agentsRetrieve = (options) => (options.client ?? client).get({
|
|
17092
17679
|
security: [{
|
|
17093
17680
|
key: "BearerAuth",
|
|
17094
17681
|
scheme: "bearer",
|
|
@@ -17098,10 +17685,10 @@ var agentsArchive = (options) => (options.client ?? client).post({
|
|
|
17098
17685
|
name: "X-API-Key",
|
|
17099
17686
|
type: "apiKey"
|
|
17100
17687
|
}],
|
|
17101
|
-
url: "/agent/v1/agents/{agent_id}
|
|
17688
|
+
url: "/agent/v1/agents/{agent_id}",
|
|
17102
17689
|
...options
|
|
17103
17690
|
});
|
|
17104
|
-
var
|
|
17691
|
+
var agentsUpdate = (options) => (options.client ?? client).post({
|
|
17105
17692
|
security: [{
|
|
17106
17693
|
key: "BearerAuth",
|
|
17107
17694
|
scheme: "bearer",
|
|
@@ -17111,10 +17698,14 @@ var agentsVersionsList = (options) => (options.client ?? client).get({
|
|
|
17111
17698
|
name: "X-API-Key",
|
|
17112
17699
|
type: "apiKey"
|
|
17113
17700
|
}],
|
|
17114
|
-
url: "/agent/v1/agents/{agent_id}
|
|
17115
|
-
...options
|
|
17701
|
+
url: "/agent/v1/agents/{agent_id}",
|
|
17702
|
+
...options,
|
|
17703
|
+
headers: {
|
|
17704
|
+
"Content-Type": "application/json",
|
|
17705
|
+
...options.headers
|
|
17706
|
+
}
|
|
17116
17707
|
});
|
|
17117
|
-
var
|
|
17708
|
+
var agentsArchive = (options) => (options.client ?? client).post({
|
|
17118
17709
|
security: [{
|
|
17119
17710
|
key: "BearerAuth",
|
|
17120
17711
|
scheme: "bearer",
|
|
@@ -17124,10 +17715,10 @@ var sessionsList = (options) => (options?.client ?? client).get({
|
|
|
17124
17715
|
name: "X-API-Key",
|
|
17125
17716
|
type: "apiKey"
|
|
17126
17717
|
}],
|
|
17127
|
-
url: "/agent/v1/
|
|
17718
|
+
url: "/agent/v1/agents/{agent_id}/archive",
|
|
17128
17719
|
...options
|
|
17129
17720
|
});
|
|
17130
|
-
var
|
|
17721
|
+
var agentsVersionsList = (options) => (options.client ?? client).get({
|
|
17131
17722
|
security: [{
|
|
17132
17723
|
key: "BearerAuth",
|
|
17133
17724
|
scheme: "bearer",
|
|
@@ -17137,14 +17728,10 @@ var sessionsCreate = (options) => (options.client ?? client).post({
|
|
|
17137
17728
|
name: "X-API-Key",
|
|
17138
17729
|
type: "apiKey"
|
|
17139
17730
|
}],
|
|
17140
|
-
url: "/agent/v1/
|
|
17141
|
-
...options
|
|
17142
|
-
headers: {
|
|
17143
|
-
"Content-Type": "application/json",
|
|
17144
|
-
...options.headers
|
|
17145
|
-
}
|
|
17731
|
+
url: "/agent/v1/agents/{agent_id}/versions",
|
|
17732
|
+
...options
|
|
17146
17733
|
});
|
|
17147
|
-
var
|
|
17734
|
+
var sessionsList = (options) => (options?.client ?? client).get({
|
|
17148
17735
|
security: [{
|
|
17149
17736
|
key: "BearerAuth",
|
|
17150
17737
|
scheme: "bearer",
|
|
@@ -17154,10 +17741,10 @@ var sessionsRetrieve = (options) => (options.client ?? client).get({
|
|
|
17154
17741
|
name: "X-API-Key",
|
|
17155
17742
|
type: "apiKey"
|
|
17156
17743
|
}],
|
|
17157
|
-
url: "/agent/v1/sessions
|
|
17744
|
+
url: "/agent/v1/sessions",
|
|
17158
17745
|
...options
|
|
17159
17746
|
});
|
|
17160
|
-
var
|
|
17747
|
+
var sessionsCreate = (options) => (options.client ?? client).post({
|
|
17161
17748
|
security: [{
|
|
17162
17749
|
key: "BearerAuth",
|
|
17163
17750
|
scheme: "bearer",
|
|
@@ -17167,7 +17754,7 @@ var sessionsUpdate = (options) => (options.client ?? client).post({
|
|
|
17167
17754
|
name: "X-API-Key",
|
|
17168
17755
|
type: "apiKey"
|
|
17169
17756
|
}],
|
|
17170
|
-
url: "/agent/v1/sessions
|
|
17757
|
+
url: "/agent/v1/sessions",
|
|
17171
17758
|
...options,
|
|
17172
17759
|
headers: {
|
|
17173
17760
|
"Content-Type": "application/json",
|
|
@@ -17668,6 +18255,15 @@ var applicationCreateVersion = (options) => (options.client ?? client).post({
|
|
|
17668
18255
|
...options.headers
|
|
17669
18256
|
}
|
|
17670
18257
|
});
|
|
18258
|
+
var applicationGetVersionAssetManifest = (options) => (options.client ?? client).get({
|
|
18259
|
+
security: [{
|
|
18260
|
+
key: "application-bearerAuth",
|
|
18261
|
+
scheme: "bearer",
|
|
18262
|
+
type: "http"
|
|
18263
|
+
}],
|
|
18264
|
+
url: "/application/v1/workers/{worker_id}/versions/{version_id}/assets/manifest",
|
|
18265
|
+
...options
|
|
18266
|
+
});
|
|
17671
18267
|
var applicationGetVersion = (options) => (options.client ?? client).get({
|
|
17672
18268
|
security: [{
|
|
17673
18269
|
key: "application-bearerAuth",
|
|
@@ -20505,6 +21101,9 @@ function createAgent(transport) {
|
|
|
20505
21101
|
},
|
|
20506
21102
|
list: bind(transport, agentsList),
|
|
20507
21103
|
retrieve: bind(transport, agentsRetrieve),
|
|
21104
|
+
unarchive: {
|
|
21105
|
+
create: bind(transport, unarchiveAgent)
|
|
21106
|
+
},
|
|
20508
21107
|
update: bind(transport, agentsUpdate),
|
|
20509
21108
|
versions: {
|
|
20510
21109
|
list: bind(transport, agentsVersionsList)
|
|
@@ -20585,6 +21184,7 @@ function createAgent(transport) {
|
|
|
20585
21184
|
list: bind(transport, listSessionCompactions)
|
|
20586
21185
|
},
|
|
20587
21186
|
create: bind(transport, sessionsCreate),
|
|
21187
|
+
delete: bind(transport, sessionsDelete),
|
|
20588
21188
|
events: {
|
|
20589
21189
|
list: bind(transport, sessionsEventsList),
|
|
20590
21190
|
send: bind(transport, sessionsEventsSend),
|
|
@@ -20666,6 +21266,9 @@ function createApplication(transport) {
|
|
|
20666
21266
|
},
|
|
20667
21267
|
update: bind(transport, applicationUpdateWorker),
|
|
20668
21268
|
versions: {
|
|
21269
|
+
assets: {
|
|
21270
|
+
retrieveManifest: bind(transport, applicationGetVersionAssetManifest)
|
|
21271
|
+
},
|
|
20669
21272
|
create: bind(transport, applicationCreateVersion),
|
|
20670
21273
|
list: bindPage(transport, applicationListVersions),
|
|
20671
21274
|
retrieve: bind(transport, applicationGetVersion)
|
|
@@ -20873,6 +21476,14 @@ function createFile(transport) {
|
|
|
20873
21476
|
list: bind(transport, fileListFiles),
|
|
20874
21477
|
retrieve: bind(transport, fileRetrieveFile),
|
|
20875
21478
|
retrieveContent: bind(transport, fileRetrieveFileContent)
|
|
21479
|
+
},
|
|
21480
|
+
uploads: {
|
|
21481
|
+
cancel: bind(transport, fileCancelUpload),
|
|
21482
|
+
complete: bind(transport, fileCompleteUpload),
|
|
21483
|
+
create: bind(transport, fileCreateUpload),
|
|
21484
|
+
parts: {
|
|
21485
|
+
create: bind(transport, (options) => fileAddUploadPart({ ...options, bodySerializer: multipartBodySerializer, headers: { "Content-Type": null, ...options.headers } }))
|
|
21486
|
+
}
|
|
20876
21487
|
}
|
|
20877
21488
|
};
|
|
20878
21489
|
}
|
|
@@ -21243,132 +21854,6 @@ var resourceFactories = {
|
|
|
21243
21854
|
vault: createVault
|
|
21244
21855
|
};
|
|
21245
21856
|
|
|
21246
|
-
// ../../packages/sdk/typescript/src/core/errors.ts
|
|
21247
|
-
function problemFrom(status, headers, body, statusText) {
|
|
21248
|
-
const value = body && typeof body === "object" ? body : {};
|
|
21249
|
-
const nested = value.error && typeof value.error === "object" ? value.error : {};
|
|
21250
|
-
const string = (v) => typeof v === "string" && v.trim() ? v : undefined;
|
|
21251
|
-
const fallback = statusText || { 400: "Bad Request", 401: "Unauthorized", 403: "Forbidden", 404: "Not Found", 405: "Method Not Allowed", 408: "Request Timeout", 409: "Conflict", 413: "Payload Too Large", 415: "Unsupported Media Type", 422: "Unprocessable Entity", 429: "Too Many Requests", 500: "Internal Server Error", 502: "Bad Gateway", 503: "Service Unavailable", 504: "Gateway Timeout" }[status] || `HTTP ${status}`;
|
|
21252
|
-
const detail = string(value.detail) ?? string(nested.message) ?? string(value.message) ?? string(body);
|
|
21253
|
-
const title = string(value.title) ?? fallback;
|
|
21254
|
-
const param = nested.param ?? value.param;
|
|
21255
|
-
return {
|
|
21256
|
-
status,
|
|
21257
|
-
message: detail ?? title,
|
|
21258
|
-
title,
|
|
21259
|
-
detail,
|
|
21260
|
-
code: string(value.code) ?? string(nested.code) ?? string(nested.type) ?? string(value.error_code),
|
|
21261
|
-
type: string(nested.type) ?? string(value.type),
|
|
21262
|
-
param: typeof param === "string" ? param : param === null || nested.param === null ? null : undefined,
|
|
21263
|
-
errors: Array.isArray(value.errors) ? value.errors : [],
|
|
21264
|
-
requestId: headers.get("x-request-id") ?? string(value.requestId) ?? string(value.request_id),
|
|
21265
|
-
raw: body
|
|
21266
|
-
};
|
|
21267
|
-
}
|
|
21268
|
-
|
|
21269
|
-
class PraxisError extends Error {
|
|
21270
|
-
status;
|
|
21271
|
-
code;
|
|
21272
|
-
type;
|
|
21273
|
-
title;
|
|
21274
|
-
detail;
|
|
21275
|
-
errors;
|
|
21276
|
-
requestId;
|
|
21277
|
-
param;
|
|
21278
|
-
raw;
|
|
21279
|
-
constructor(problem = {}, options) {
|
|
21280
|
-
super(problem.message ?? problem.detail ?? problem.title ?? `Praxis request failed${problem.status ? ` (${problem.status})` : ""}`, options);
|
|
21281
|
-
this.name = "PraxisError";
|
|
21282
|
-
this.status = problem.status;
|
|
21283
|
-
this.code = problem.code;
|
|
21284
|
-
this.type = problem.type;
|
|
21285
|
-
this.title = problem.title;
|
|
21286
|
-
this.detail = problem.detail;
|
|
21287
|
-
this.errors = problem.errors ?? [];
|
|
21288
|
-
this.requestId = problem.requestId;
|
|
21289
|
-
this.param = problem.param;
|
|
21290
|
-
this.raw = problem.raw;
|
|
21291
|
-
}
|
|
21292
|
-
static fromResponse(response, body) {
|
|
21293
|
-
return new PraxisError(problemFrom(response.status, response.headers, body, response.statusText));
|
|
21294
|
-
}
|
|
21295
|
-
}
|
|
21296
|
-
|
|
21297
|
-
class PraxisConnectionError extends PraxisError {
|
|
21298
|
-
constructor(cause) {
|
|
21299
|
-
super({ code: "CONNECTION_ERROR", title: "Unable to connect to Praxis" }, { cause });
|
|
21300
|
-
this.name = "PraxisConnectionError";
|
|
21301
|
-
}
|
|
21302
|
-
}
|
|
21303
|
-
|
|
21304
|
-
class PraxisTimeoutError extends PraxisError {
|
|
21305
|
-
constructor(timeoutMs) {
|
|
21306
|
-
super({ code: "TIMEOUT", title: `Praxis request exceeded ${timeoutMs} ms` });
|
|
21307
|
-
this.name = "PraxisTimeoutError";
|
|
21308
|
-
}
|
|
21309
|
-
}
|
|
21310
|
-
|
|
21311
|
-
// ../../packages/sdk/typescript/src/core/retry.ts
|
|
21312
|
-
function canRetry(request) {
|
|
21313
|
-
return request.method !== "POST" || Boolean(request.headers.get("Idempotency-Key")?.trim());
|
|
21314
|
-
}
|
|
21315
|
-
function retryAfterMs(value, now = Date.now()) {
|
|
21316
|
-
if (!value)
|
|
21317
|
-
return;
|
|
21318
|
-
if (/^\d+(?:\.\d+)?$/.test(value.trim()))
|
|
21319
|
-
return Number(value) * 1000;
|
|
21320
|
-
const date = Date.parse(value);
|
|
21321
|
-
return Number.isFinite(date) ? Math.max(0, date - now) : undefined;
|
|
21322
|
-
}
|
|
21323
|
-
function retryDelay(attempt, retryAfter, random = Math.random) {
|
|
21324
|
-
return retryAfterMs(retryAfter) ?? Math.min(30000, 500 * 2 ** attempt) * (0.5 + random() * 0.5);
|
|
21325
|
-
}
|
|
21326
|
-
function abortable(promise, signal) {
|
|
21327
|
-
signal.throwIfAborted();
|
|
21328
|
-
return new Promise((resolve, reject) => {
|
|
21329
|
-
const abort = () => reject(signal.reason);
|
|
21330
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
21331
|
-
promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
21332
|
-
});
|
|
21333
|
-
}
|
|
21334
|
-
function sleep(ms, signal) {
|
|
21335
|
-
signal.throwIfAborted();
|
|
21336
|
-
return new Promise((resolve, reject) => {
|
|
21337
|
-
const abort = () => {
|
|
21338
|
-
clearTimeout(timer);
|
|
21339
|
-
reject(signal.reason);
|
|
21340
|
-
};
|
|
21341
|
-
const timer = setTimeout(() => {
|
|
21342
|
-
signal.removeEventListener("abort", abort);
|
|
21343
|
-
resolve();
|
|
21344
|
-
}, ms);
|
|
21345
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
21346
|
-
});
|
|
21347
|
-
}
|
|
21348
|
-
async function fetchWithRetry(request, fetcher, options) {
|
|
21349
|
-
const eligible = canRetry(request);
|
|
21350
|
-
const wait = options.wait ?? sleep;
|
|
21351
|
-
for (let attempt = 0;; attempt++) {
|
|
21352
|
-
options.signal.throwIfAborted();
|
|
21353
|
-
let response;
|
|
21354
|
-
try {
|
|
21355
|
-
response = await abortable(fetcher(request.clone()), options.signal);
|
|
21356
|
-
} catch (cause) {
|
|
21357
|
-
options.signal.throwIfAborted();
|
|
21358
|
-
if (!eligible || attempt >= options.maxRetries)
|
|
21359
|
-
throw new PraxisConnectionError(cause);
|
|
21360
|
-
await wait(retryDelay(attempt, null, options.random), options.signal);
|
|
21361
|
-
continue;
|
|
21362
|
-
}
|
|
21363
|
-
const retriable = response.status === 408 || response.status === 429 || response.status >= 500 && response.status <= 599;
|
|
21364
|
-
if (!eligible || !retriable || attempt >= options.maxRetries)
|
|
21365
|
-
return response;
|
|
21366
|
-
const delay = retryDelay(attempt, response.headers.get("Retry-After"), options.random);
|
|
21367
|
-
await response.body?.cancel();
|
|
21368
|
-
await wait(delay, options.signal);
|
|
21369
|
-
}
|
|
21370
|
-
}
|
|
21371
|
-
|
|
21372
21857
|
// ../../packages/sdk/typescript/src/core/sse.ts
|
|
21373
21858
|
async function* parseSSE(body, options = {}) {
|
|
21374
21859
|
const reader = body.getReader();
|
|
@@ -21582,9 +22067,13 @@ class Transport {
|
|
|
21582
22067
|
};
|
|
21583
22068
|
}
|
|
21584
22069
|
async request(operation, options = {}) {
|
|
22070
|
+
return (await this.requestWithResponse(operation, options)).data;
|
|
22071
|
+
}
|
|
22072
|
+
async requestWithResponse(operation, options = {}) {
|
|
21585
22073
|
const scope = this.scope(options, false);
|
|
21586
22074
|
try {
|
|
21587
|
-
|
|
22075
|
+
const result = await abortable(operation(scope.options), scope.signal);
|
|
22076
|
+
return { data: result.data, response: result.response };
|
|
21588
22077
|
} finally {
|
|
21589
22078
|
scope.close();
|
|
21590
22079
|
}
|
|
@@ -21616,6 +22105,10 @@ function base64(bytes) {
|
|
|
21616
22105
|
return btoa(chunks.join(""));
|
|
21617
22106
|
}
|
|
21618
22107
|
async function publish(client2, input) {
|
|
22108
|
+
const rolloutFields = ["gradual", "gradualRollout", "gradual_rollout", "canary", "rollout", "percentage", "percent", "traffic", "traffic_percentage", "strategy", "versions"];
|
|
22109
|
+
if (Object.keys(input).some((key) => rolloutFields.includes(key) || /percentage|percent|canary|gradual|rollout|灰度/i.test(key))) {
|
|
22110
|
+
throw new PraxisError({ code: "INVALID_PARAMS", message: '平台不支持灰度 (gradual rollout is not supported). Roll back with praxis.application.workers.deployments.create({ path: { worker_id }, body: { strategy: "percentage", versions: [{ version_id: previousVersionId, percentage: 100 }] } }); the previous version artifacts must still be retained.' });
|
|
22111
|
+
}
|
|
21619
22112
|
const timeout = input.timeout_ms ?? 120000;
|
|
21620
22113
|
if (!Number.isFinite(timeout) || timeout < 0)
|
|
21621
22114
|
throw new RangeError("timeout_ms must be non-negative and finite");
|
|
@@ -21634,7 +22127,7 @@ async function publish(client2, input) {
|
|
|
21634
22127
|
const files = Object.entries(input.files);
|
|
21635
22128
|
if (files.length > 1e5)
|
|
21636
22129
|
throw new PraxisError({ code: "LIMIT_EXCEEDED", message: "At most 100000 asset paths can be published" });
|
|
21637
|
-
|
|
22130
|
+
let manifest = {};
|
|
21638
22131
|
const contents = new Map;
|
|
21639
22132
|
for (const [path2, content] of files) {
|
|
21640
22133
|
const normalized = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
@@ -21643,8 +22136,8 @@ async function publish(client2, input) {
|
|
|
21643
22136
|
const bytes = typeof content === "string" ? new TextEncoder().encode(content) : new Uint8Array(content);
|
|
21644
22137
|
if (bytes.length > FILE_BYTES)
|
|
21645
22138
|
throw new PraxisError({ code: "LIMIT_EXCEEDED", message: `Asset ${normalized} exceeds 25 MiB` });
|
|
21646
|
-
const
|
|
21647
|
-
const hash = Array.from(
|
|
22139
|
+
const digest2 = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
22140
|
+
const hash = Array.from(digest2.subarray(0, 16), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
21648
22141
|
manifest[normalized] = { hash, size: bytes.length };
|
|
21649
22142
|
contents.set(hash, bytes);
|
|
21650
22143
|
}
|
|
@@ -21657,9 +22150,60 @@ async function publish(client2, input) {
|
|
|
21657
22150
|
}
|
|
21658
22151
|
}
|
|
21659
22152
|
const created = !worker;
|
|
22153
|
+
if (!worker && input.dryRun)
|
|
22154
|
+
throw new PraxisError({ code: "NOT_FOUND", message: "请先创建应用 (create the application before dryRun)" });
|
|
21660
22155
|
worker ??= await workers.create({ body: { name: input.name, subdomain: { enabled: true } } });
|
|
21661
22156
|
const path = { worker_id: worker.id };
|
|
22157
|
+
let currentVersion;
|
|
22158
|
+
let currentDeployment;
|
|
22159
|
+
let previous = {};
|
|
22160
|
+
if (worker.praxis?.current_deployment_id) {
|
|
22161
|
+
currentDeployment = await workers.deployments.retrieve({ path: { ...path, deployment_id: worker.praxis.current_deployment_id } });
|
|
22162
|
+
const active = currentDeployment.versions[0];
|
|
22163
|
+
if (!active)
|
|
22164
|
+
throw new PraxisError({ code: "INVALID_RESPONSE", message: "Current deployment has no version" });
|
|
22165
|
+
currentVersion = await workers.versions.retrieve({ path: { ...path, version_id: active.version_id } });
|
|
22166
|
+
previous = (await workers.versions.assets.retrieveManifest({ path: { ...path, version_id: active.version_id } })).manifest;
|
|
22167
|
+
}
|
|
22168
|
+
manifest = {
|
|
22169
|
+
...Object.fromEntries(Object.entries(previous).filter(([key]) => input.keepExisting || Object.hasOwn(manifest, key))),
|
|
22170
|
+
...manifest
|
|
22171
|
+
};
|
|
22172
|
+
if (Object.keys(manifest).length > 1e5)
|
|
22173
|
+
throw new PraxisError({ code: "LIMIT_EXCEEDED", message: "At most 100000 asset paths can be published" });
|
|
22174
|
+
const added = Object.keys(manifest).filter((key) => !Object.hasOwn(previous, key));
|
|
22175
|
+
const changed = Object.keys(manifest).filter((key) => previous[key] && (previous[key].hash !== manifest[key].hash || previous[key].size !== manifest[key].size));
|
|
22176
|
+
const removed = Object.keys(previous).filter((key) => !Object.hasOwn(manifest, key));
|
|
22177
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify(manifest))));
|
|
22178
|
+
const manifestHash = Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
22179
|
+
const staticOnly = !["main", "bindings", "compatibility_date", "compatibility_flags", "assets_config"].some((key) => Object.hasOwn(input, key));
|
|
22180
|
+
const unchanged = staticOnly && !!currentVersion && manifestHash === currentVersion.praxis.assets_manifest?.manifest_hash;
|
|
22181
|
+
const hashes = new Set(Object.values(manifest).map((entry) => entry.hash));
|
|
22182
|
+
const currentResult = {
|
|
22183
|
+
url: worker.subdomain.url,
|
|
22184
|
+
worker_id: worker.id,
|
|
22185
|
+
version_id: currentVersion?.id ?? null,
|
|
22186
|
+
deployment_id: currentDeployment?.id ?? null,
|
|
22187
|
+
status: currentDeployment?.praxis.status ?? "draft",
|
|
22188
|
+
created,
|
|
22189
|
+
...currentVersion ? { version: currentVersion } : {},
|
|
22190
|
+
unchanged,
|
|
22191
|
+
uploaded: 0,
|
|
22192
|
+
reused: hashes.size
|
|
22193
|
+
};
|
|
22194
|
+
if (unchanged && !input.dryRun)
|
|
22195
|
+
return currentResult;
|
|
21662
22196
|
const session = await workers.assetsUploadSession.create({ path, body: { manifest } });
|
|
22197
|
+
if (input.dryRun) {
|
|
22198
|
+
const missing = new Set(session.buckets.flat());
|
|
22199
|
+
if ([...missing].some((hash) => !hashes.has(hash)))
|
|
22200
|
+
throw new PraxisError({ code: "INVALID_RESPONSE", message: "Upload session requested an unknown hash" });
|
|
22201
|
+
return {
|
|
22202
|
+
...currentResult,
|
|
22203
|
+
reused: hashes.size - missing.size,
|
|
22204
|
+
plan: { added, changed, removed, upload_hashes: missing.size, existing_hashes: hashes.size - missing.size }
|
|
22205
|
+
};
|
|
22206
|
+
}
|
|
21663
22207
|
let jwt = session.buckets.length ? null : session.jwt;
|
|
21664
22208
|
const uploaded = new Set;
|
|
21665
22209
|
for (const bucket of session.buckets) {
|
|
@@ -21730,16 +22274,31 @@ async function publish(client2, input) {
|
|
|
21730
22274
|
status: deployment.praxis.status,
|
|
21731
22275
|
created,
|
|
21732
22276
|
uploaded: uploaded.size,
|
|
21733
|
-
reused:
|
|
22277
|
+
reused: hashes.size - uploaded.size
|
|
21734
22278
|
};
|
|
21735
22279
|
}
|
|
21736
22280
|
|
|
22281
|
+
// ../../packages/sdk/typescript/src/helpers/database-count.ts
|
|
22282
|
+
async function count(transport, input) {
|
|
22283
|
+
const { response } = await transport.requestWithResponse(databaseHead, {
|
|
22284
|
+
path: { database_id: input.database_id, table: input.table },
|
|
22285
|
+
query: input.filters,
|
|
22286
|
+
headers: { Prefer: `count=${input.count ?? "exact"}` }
|
|
22287
|
+
});
|
|
22288
|
+
const total = response.headers.get("Content-Range")?.split("/")[1];
|
|
22289
|
+
return { count: total === undefined || total === "*" ? null : Number(total) };
|
|
22290
|
+
}
|
|
22291
|
+
|
|
21737
22292
|
// ../../packages/sdk/typescript/src/core/client.ts
|
|
21738
22293
|
class Praxis {
|
|
21739
22294
|
constructor(options) {
|
|
21740
22295
|
const transport = new Transport(options);
|
|
21741
22296
|
for (const [name, create] of Object.entries(resourceFactories)) {
|
|
21742
22297
|
const resource = create(transport);
|
|
22298
|
+
if (name === "file")
|
|
22299
|
+
Object.assign(resource, { uploadFile: (file, options2) => uploadFile(this, file, options2) });
|
|
22300
|
+
if (name === "database")
|
|
22301
|
+
Object.assign(resource, { count: (input) => count(transport, input) });
|
|
21743
22302
|
if (name === "application")
|
|
21744
22303
|
Object.assign(resource, { publish: (input) => publish(this, input) });
|
|
21745
22304
|
Object.defineProperty(this, name, { value: resource, enumerable: true });
|
|
@@ -22871,7 +23430,7 @@ function plain(value) {
|
|
|
22871
23430
|
}
|
|
22872
23431
|
|
|
22873
23432
|
// src/output/human.ts
|
|
22874
|
-
var
|
|
23433
|
+
var count3 = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
22875
23434
|
function identity(result, ctx) {
|
|
22876
23435
|
const op = "op" in result ? result.op : undefined;
|
|
22877
23436
|
const split = op?.lastIndexOf(".") ?? -1;
|
|
@@ -22959,7 +23518,7 @@ function objectView(data, resource, id, ctx, paint) {
|
|
|
22959
23518
|
return v.map(scalar).map(plain).join(", ");
|
|
22960
23519
|
folded = true;
|
|
22961
23520
|
const preview = v.slice(0, 3).map((item) => record(item).id ?? record(item).name).filter((x) => x !== undefined).map((x) => plain(scalar(x)));
|
|
22962
|
-
return `${
|
|
23521
|
+
return `${count3(v.length, "item")}${preview.length ? ` (${preview.join(", ")})` : ""}`;
|
|
22963
23522
|
}
|
|
22964
23523
|
if (v !== null && typeof v === "object") {
|
|
22965
23524
|
if (depth >= 1) {
|
|
@@ -23000,7 +23559,7 @@ function renderHuman(result, ctx) {
|
|
|
23000
23559
|
return {
|
|
23001
23560
|
stdout: result.items.length ? table(result.items, ctx, out) : out.dim(`No ${plain(resource)}${/(s|x|ch|sh)$/.test(resource) ? "es" : "s"}.`) + `
|
|
23002
23561
|
`,
|
|
23003
|
-
stderr: err.dim(`${result.total !== undefined ? `${result.items.length} of ${result.total} items` :
|
|
23562
|
+
stderr: err.dim(`${result.total !== undefined ? `${result.items.length} of ${result.total} items` : count3(result.items.length, "item")}${result.nextCursor ? ` · next: ${ctx.nextCommand ?? "praxis --help"}` : ""}`) + `
|
|
23004
23563
|
`
|
|
23005
23564
|
};
|
|
23006
23565
|
case "object": {
|
|
@@ -23280,7 +23839,7 @@ function startProgress(ctx, write = (text) => writeOutput({ stderr: text })) {
|
|
|
23280
23839
|
}
|
|
23281
23840
|
|
|
23282
23841
|
// src/main.ts
|
|
23283
|
-
var version = "0.1.0-dev.
|
|
23842
|
+
var version = "0.1.0-dev.6898104";
|
|
23284
23843
|
var commands = commandTree(operations);
|
|
23285
23844
|
var manual = [["login"], ["logout"], ["whoami"], ["org", "list"], ["org", "switch"], ["api"], ["skill"]];
|
|
23286
23845
|
function route(argv) {
|