@deepraxis/cli 0.1.0-dev.9d9e2b6 → 0.1.0-dev.a3beed2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/COMMANDS.md +26 -6
  2. package/dist/praxis.js +1371 -297
  3. package/package.json +1 -1
package/dist/praxis.js CHANGED
@@ -68,7 +68,7 @@ var operations = [
68
68
  resource: "agent.agents",
69
69
  method: "create",
70
70
  summary: "Create agent",
71
- description: 'Create a reusable agent definition, then pass its returned id to sessions.create to start a conversation. The definition includes model, system prompt, tools, MCP servers and an optional multiagent roster. It is saved as version 1; real updates create new versions. Unlike Anthropic Managed Agents, nonempty skills attachments and custom tool entries return 400; the native skill tool is separate from the skills field. Use tools: [{type: "agent_toolset_20260401"}] for built-in tools including codemode, skill and agent; inspect toolsets.list for names and schemas, and keep bash enabled for native additions. To offer only some tools, set default_config: {enabled: false} and list the tools to keep in configs, e.g. tools: [{type: "agent_toolset_20260401", default_config: {enabled: false}, configs: [{name: "codemode", enabled: true}, {name: "bash", enabled: true, permission_policy: {type: "always_ask"}}]}]; every tool not listed, including todo_write, enter_plan_mode, ask_user_question and goal_read, follows default_config, and the response echoes it. codemode runs through bash, so enabling codemode while bash is disabled returns 400. Optional mcp_toolset entries pair with mcp_servers. model accepts platform model IDs such as deepseek-flash, not only the Claude IDs in the protocol examples. model.settings.reasoning sets default thinking; other extra model controls return 400. Example: {"name":"helper","model":{"id":"deepseek-flash"},"tools":[{"type":"agent_toolset_20260401"}]}.',
71
+ description: 'Create a reusable agent definition, then pass its returned id to sessions.create to start a conversation. The definition includes model, system prompt, tools, MCP servers and an optional multiagent roster. It is saved as version 1; real updates create new versions. Unlike Anthropic Managed Agents, nonempty skills attachments return 400; the native skill tool is separate from the skills field. Use tools: [{type: "agent_toolset_20260401"}] for built-in tools including codemode, skill and agent; inspect toolsets.list for names and schemas, and keep bash enabled for native additions. To offer only some tools, set default_config: {enabled: false} and list the tools to keep in configs, e.g. tools: [{type: "agent_toolset_20260401", default_config: {enabled: false}, configs: [{name: "codemode", enabled: true}, {name: "bash", enabled: true, permission_policy: {type: "always_ask"}}]}]; every tool not listed, including todo_write, enter_plan_mode, ask_user_question and goal_read, follows default_config, and the response echoes it. codemode runs through bash, so enabling codemode while bash is disabled returns 400. Optional mcp_toolset entries pair with mcp_servers. model accepts platform model IDs such as deepseek-flash, not only the Claude IDs in the protocol examples. model.settings.reasoning sets default thinking; other extra model controls return 400. Example: {"name":"helper","model":{"id":"deepseek-flash"},"tools":[{"type":"agent_toolset_20260401"}]}.',
72
72
  http: "POST",
73
73
  path: "/agent/v1/agents",
74
74
  streaming: "no",
@@ -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
  }
@@ -215,7 +247,7 @@ across all toolsets allowed.`
215
247
  resource: "agent.agents",
216
248
  method: "update",
217
249
  summary: "Update agent",
218
- description: "Update an agent. Send the current version in the body for optimistic concurrency: a stale version returns 409, and an update that changes nothing keeps the version number. Any real change saves a new version; existing sessions keep the version they were created with. Omitted fields keep their value. multiagent takes null or a coordinator roster; subagent_model keeps its value when omitted and is cleared by null. Archived agents cannot be updated. Unlike Anthropic Managed Agents, nonempty skills attachments and custom tools return 400; use the native skill tool for available runtime skills.",
250
+ description: "Update an agent. Send the current version in the body for optimistic concurrency: a stale version returns 409, and an update that changes nothing keeps the version number. Any real change saves a new version; existing sessions keep the version they were created with. Omitted fields keep their value. multiagent takes null or a coordinator roster; subagent_model keeps its value when omitted and is cleared by null. Archived agents cannot be updated. Unlike Anthropic Managed Agents, nonempty skills attachments return 400; use the native skill tool for available runtime skills.",
219
251
  http: "POST",
220
252
  path: "/agent/v1/agents/{agent_id}",
221
253
  streaming: "no",
@@ -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
  }
@@ -369,6 +433,206 @@ current version; omit to apply the update unconditionally.`
369
433
  ],
370
434
  query: []
371
435
  },
436
+ {
437
+ resource: "agent.agents.endUsers",
438
+ method: "list",
439
+ summary: "List End Users",
440
+ description: `List users who have sessions or token issuance history on a service agent.
441
+
442
+ Ordered by last_active_at and external_user_id descending. q is a case-sensitive literal prefix, including underscores. limit is 1–100, default 20. Reuse next_page with the same organization, agent, q and limit. Preemptively blocked users without history do not appear. End-user credentials and inaccessible or personal agents return 404.`,
443
+ http: "GET",
444
+ path: "/agent/v1/agents/{agent_id}/end_users",
445
+ streaming: "no",
446
+ pagination: false,
447
+ pathParams: [
448
+ {
449
+ name: "agent_id",
450
+ sdkName: "agent_id"
451
+ }
452
+ ],
453
+ query: [
454
+ {
455
+ name: "limit",
456
+ type: "integer",
457
+ required: false,
458
+ description: "Maximum users per page; defaults to 20."
459
+ },
460
+ {
461
+ name: "page",
462
+ type: "string",
463
+ required: false,
464
+ description: "next_page from the previous response with the same agent, q and limit."
465
+ },
466
+ {
467
+ name: "q",
468
+ type: "string",
469
+ required: false,
470
+ description: "Case-sensitive literal prefix of external_user_id; omit or use an empty string for all users."
471
+ }
472
+ ]
473
+ },
474
+ {
475
+ resource: "agent.agents.endUsers",
476
+ method: "delete",
477
+ summary: "Delete end-user data",
478
+ description: `Delete a host application's end-user data from one service agent after explicit confirmation.
479
+
480
+ Develop only. Set confirm to the exact external_user_id; missing or mismatched confirmation returns 400. Returns 202 with a pending task id, not completion. Poll the deletion endpoint. Concurrent requests reuse the unfinished task; retry DELETE after failure to resume it. Tokens are revoked and the user is blocked before a seven-day recovery snapshot is verified. Sessions including child sessions, conversation data, grants and feedback are then removed. A pre-existing block remains; a temporary block is removed on success. Attachment metadata is recorded and File attachments are retained. No charge is introduced by this operation. Example: DELETE /agent/v1/agents/agent_example/end_users/customer_123?confirm=customer_123.`,
481
+ http: "DELETE",
482
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
483
+ streaming: "no",
484
+ pagination: false,
485
+ pathParams: [
486
+ {
487
+ name: "agent_id",
488
+ sdkName: "agent_id"
489
+ },
490
+ {
491
+ name: "external_user_id",
492
+ sdkName: "external_user_id"
493
+ }
494
+ ],
495
+ query: [
496
+ {
497
+ name: "confirm",
498
+ type: "string",
499
+ required: true,
500
+ description: "Must exactly equal the external_user_id path parameter to confirm destructive deletion."
501
+ }
502
+ ]
503
+ },
504
+ {
505
+ resource: "agent.agents.endUsers",
506
+ method: "retrieve",
507
+ summary: "Get End User",
508
+ description: `Inspect one end user and their twenty most recently updated sessions.
509
+
510
+ Use external_user_id from listing or your host application. Users without session or issuance history return 404, including preemptively blocked users. End-user credentials and inaccessible or personal agents return 404.`,
511
+ http: "GET",
512
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
513
+ streaming: "no",
514
+ pagination: false,
515
+ pathParams: [
516
+ {
517
+ name: "agent_id",
518
+ sdkName: "agent_id"
519
+ },
520
+ {
521
+ name: "external_user_id",
522
+ sdkName: "external_user_id"
523
+ }
524
+ ],
525
+ query: []
526
+ },
527
+ {
528
+ resource: "agent.agents.endUsers.block",
529
+ method: "create",
530
+ summary: "Block End User",
531
+ description: `Block token issuance and session creation, then revoke existing tokens for an end user.
532
+
533
+ May block a user before any history exists; timestamps are then null and counts and cost are zero. Requires an embed policy, otherwise returns 409 with setup guidance. Deduplicates the policy blocklist and retains its 1000-user maximum. If revocation returns 502, the user remains blocked; retry to finish revocation. Repeats keep the user blocked and revoke any remaining grants. End-user credentials and inaccessible or personal agents return 404.`,
534
+ http: "POST",
535
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/block",
536
+ streaming: "no",
537
+ pagination: false,
538
+ pathParams: [
539
+ {
540
+ name: "agent_id",
541
+ sdkName: "agent_id"
542
+ },
543
+ {
544
+ name: "external_user_id",
545
+ sdkName: "external_user_id"
546
+ }
547
+ ],
548
+ query: []
549
+ },
550
+ {
551
+ resource: "agent.agents.endUsers",
552
+ method: "retrieveDeletion",
553
+ summary: "Get end-user deletion",
554
+ description: `Poll the latest deletion task for an end user, including after the user data has been removed.
555
+
556
+ Use the same agent_id and external_user_id as the confirmed DELETE. Status is pending, snapshotting, deleting, done or failed. Counts are empty until a verified snapshot exists. A failed task remains blocked and resumes when DELETE is retried with matching confirmation. snapshot_key is an operator recovery reference retained for seven days, not a public download URL. End-user credentials, inaccessible or personal agents, and missing tasks return 404. This read does not create a task or charge usage.`,
557
+ http: "GET",
558
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/deletion",
559
+ streaming: "no",
560
+ pagination: false,
561
+ pathParams: [
562
+ {
563
+ name: "agent_id",
564
+ sdkName: "agent_id"
565
+ },
566
+ {
567
+ name: "external_user_id",
568
+ sdkName: "external_user_id"
569
+ }
570
+ ],
571
+ query: []
572
+ },
573
+ {
574
+ resource: "agent.agents.endUsers.revokeTokens",
575
+ method: "create",
576
+ summary: "Revoke End User Tokens",
577
+ description: `Revoke all issued tokens for an end user and terminate their open embed streams.
578
+
579
+ Revokes credentials before marking grants revoked. Upstream failure returns 502 without changing grant revocation timestamps. Returns the count of newly revoked grants; a repeat without new grants returns zero. Does not block future issuance. End-user credentials and inaccessible or personal agents return 404.`,
580
+ http: "POST",
581
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/revoke_tokens",
582
+ streaming: "no",
583
+ pagination: false,
584
+ pathParams: [
585
+ {
586
+ name: "agent_id",
587
+ sdkName: "agent_id"
588
+ },
589
+ {
590
+ name: "external_user_id",
591
+ sdkName: "external_user_id"
592
+ }
593
+ ],
594
+ query: []
595
+ },
596
+ {
597
+ resource: "agent.agents.endUsers.unblock",
598
+ method: "create",
599
+ summary: "Unblock End User",
600
+ description: `Allow an end user to receive new tokens and create new sessions again.
601
+
602
+ Removes the user from the blocklist; previously revoked tokens stay revoked. Idempotent. Requires an embed policy, otherwise returns 409 with setup guidance. Returns null timestamps and zero counts and cost when no session or issuance history exists. End-user credentials and inaccessible or personal agents return 404.`,
603
+ http: "POST",
604
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/unblock",
605
+ streaming: "no",
606
+ pagination: false,
607
+ pathParams: [
608
+ {
609
+ name: "agent_id",
610
+ sdkName: "agent_id"
611
+ },
612
+ {
613
+ name: "external_user_id",
614
+ sdkName: "external_user_id"
615
+ }
616
+ ],
617
+ query: []
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
+ },
372
636
  {
373
637
  resource: "agent.agents.versions",
374
638
  method: "list",
@@ -580,7 +844,9 @@ Own-face superset: Managed Agents has no persistent Computer attachment director
580
844
  summary: "Connect computer",
581
845
  description: `Resume the computer and issue a sandbox connection.
582
846
 
583
- Own-face extension: Managed Agents has no persistent Computer connection. Returns the public SDK sandbox_id, envd_access_token and template_id. 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.`,
584
850
  http: "POST",
585
851
  path: "/agent/v1/computers/{computer_id}/connect",
586
852
  streaming: "no",
@@ -591,7 +857,22 @@ Own-face extension: Managed Agents has no persistent Computer connection. Return
591
857
  sdkName: "computer_id"
592
858
  }
593
859
  ],
594
- 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
+ }
595
876
  },
596
877
  {
597
878
  resource: "agent.computers.files",
@@ -645,6 +926,52 @@ Praxis extension: MA only has session-scoped temporary containers and memory_sto
645
926
  }
646
927
  ]
647
928
  },
929
+ {
930
+ resource: "agent.computers.leases",
931
+ method: "delete",
932
+ summary: "Release computer lease",
933
+ description: `Give the lease back when a connection closes so the full machine can be reclaimed without waiting for it to expire.
934
+
935
+ Own-face extension. Idempotent: an unknown or already released lease succeeds as well. Foreign or absent computers return 404.`,
936
+ http: "DELETE",
937
+ path: "/agent/v1/computers/{computer_id}/leases/{lease_id}",
938
+ streaming: "no",
939
+ pagination: false,
940
+ pathParams: [
941
+ {
942
+ name: "computer_id",
943
+ sdkName: "computer_id"
944
+ },
945
+ {
946
+ name: "lease_id",
947
+ sdkName: "lease_id"
948
+ }
949
+ ],
950
+ query: []
951
+ },
952
+ {
953
+ resource: "agent.computers.leases.renew",
954
+ method: "create",
955
+ summary: "Renew computer lease",
956
+ description: `Extend the lease a connection holds so the full machine stays in service while the connection is open.
957
+
958
+ Own-face extension. A lease that is no longer valid (released, expired, or the computer moved to another machine) returns 409 LEASE_STALE; call connect again for a new connection and lease. Foreign or absent computers return 404.`,
959
+ http: "POST",
960
+ path: "/agent/v1/computers/{computer_id}/leases/{lease_id}/renew",
961
+ streaming: "no",
962
+ pagination: false,
963
+ pathParams: [
964
+ {
965
+ name: "computer_id",
966
+ sdkName: "computer_id"
967
+ },
968
+ {
969
+ name: "lease_id",
970
+ sdkName: "lease_id"
971
+ }
972
+ ],
973
+ query: []
974
+ },
648
975
  {
649
976
  resource: "agent.deploymentRuns",
650
977
  method: "list",
@@ -1074,6 +1401,43 @@ null to clear. Maximum 50.`
1074
1401
  ],
1075
1402
  query: []
1076
1403
  },
1404
+ {
1405
+ resource: "agent.embed",
1406
+ method: "retrieveAppearance",
1407
+ summary: "Read chat appearance",
1408
+ description: "Load saved appearance for an iframe or Hosted chat page. Supply an end-user embed token as Bearer authorization, or a console-issued publishable key in Praxis-Publishable-Key before anonymous token issuance. The credential selects the agent; identity_number and agent_id query parameters are rejected with 400. Missing appearance returns an empty object. Kit option names retain camelCase. Responses are private and cacheable for 60 seconds. Component hosts configure Kit in their own code instead.",
1409
+ http: "GET",
1410
+ path: "/agent/v1/embed/appearance",
1411
+ streaming: "no",
1412
+ pagination: false,
1413
+ pathParams: [],
1414
+ query: []
1415
+ },
1416
+ {
1417
+ resource: "agent.embed.exchange",
1418
+ method: "create",
1419
+ summary: "Exchange Hosted Code",
1420
+ description: `Redeem a single-use hosted link credential for an end-user token.
1421
+
1422
+ Read code from the c fragment parameter of hosted_url returned by embed token creation with hosted true, then remove the fragment before exchanging. No Authorization header is required; the code authenticates this request. The code expires after 60 seconds and is consumed atomically on exchange, so concurrent attempts have only one winner. Expired, used and unknown codes return the same 404 body. Keep the token in memory and return to the host website for a fresh link when it expires; exchange cannot refresh it. Requests are IP limited per minute using the anonymous entrypoint budget (default 20). Example body is {"code":"<code from hosted_url>"}.`,
1423
+ http: "POST",
1424
+ path: "/agent/v1/embed/exchange",
1425
+ streaming: "no",
1426
+ pagination: false,
1427
+ pathParams: [],
1428
+ query: [],
1429
+ body: {
1430
+ required: true,
1431
+ fields: [
1432
+ {
1433
+ name: "code",
1434
+ type: "string",
1435
+ required: true,
1436
+ description: "Single-use credential from the c fragment parameter of hosted_url returned by embed token creation. Valid for 60 seconds."
1437
+ }
1438
+ ]
1439
+ }
1440
+ },
1077
1441
  {
1078
1442
  resource: "agent.embedTokens",
1079
1443
  method: "list",
@@ -1119,7 +1483,7 @@ Includes expired and revoked grants; returns neither token nor token_id. Sorts b
1119
1483
  summary: "Create Embed Token",
1120
1484
  description: `Issue a short-lived credential on your backend for an end user of a service agent.
1121
1485
 
1122
- Requires an active service agent in your organization with an embed policy. Pins the requested version or the latest version and snapshots the policy environment, vaults and resources; metadata comes from the request. Blocked users cannot receive tokens. Keep your API key on the backend and pass only the returned token to the frontend. Every call creates a new grant; issuance is not idempotent. The hosted field is not supported.`,
1486
+ Requires an active service agent in your organization with an embed policy. Pins the requested version or the latest version and snapshots the policy environment, vaults and resources; metadata comes from the request. Blocked users cannot receive tokens. Keep your API key on the backend and pass only the returned token to the frontend. Every call creates a new grant; issuance is not idempotent. Set hosted to true to also receive hosted_url; redirect the user there within 60 seconds. The agent must have an identity_number. The URL fragment contains a single-use exchange credential, not the token. Omit hosted or set false for ordinary token issuance.`,
1123
1487
  http: "POST",
1124
1488
  path: "/agent/v1/embed_tokens",
1125
1489
  streaming: "no",
@@ -1129,6 +1493,12 @@ Requires an active service agent in your organization with an embed policy. Pins
1129
1493
  body: {
1130
1494
  required: true,
1131
1495
  fields: [
1496
+ {
1497
+ name: "hosted",
1498
+ type: "boolean",
1499
+ required: false,
1500
+ description: "Set true to also return a hosted chat URL with a single-use credential valid for 60 seconds. Defaults to false; the agent must have an identity_number."
1501
+ },
1132
1502
  {
1133
1503
  name: "agent",
1134
1504
  type: "string",
@@ -1188,6 +1558,37 @@ Requires an active service agent in your organization with an embed policy. Pins
1188
1558
  ]
1189
1559
  }
1190
1560
  },
1561
+ {
1562
+ resource: "agent.embedTokens.anonymous",
1563
+ method: "create",
1564
+ summary: "Issue anonymous visitor token",
1565
+ description: `Obtain a short-lived embedding token for a visitor without an account using the agent owner's publishable key.
1566
+
1567
+ No Authorization header is required. Send the browser Origin allowed by the agent policy. Save a returned visitor_secret and reuse it for refreshes; only new visitors receive one. Unknown secrets create new visitors, and extra fields including visitor_id return 400. Issuance uses the key creator's organization membership, the key session budget and the smaller of the policy TTL maximum and 3600 seconds. IP requests are limited per minute (default 20); UTC daily session and spending caps are checked across the key's primary sessions created that day. Token issuance itself does not create a session or charge usage; subsequent sessions bill the host organization. Example body: {"publishable_key":"pk_praxis_example"}.`,
1568
+ http: "POST",
1569
+ path: "/agent/v1/embed_tokens/anonymous",
1570
+ streaming: "no",
1571
+ pagination: false,
1572
+ pathParams: [],
1573
+ query: [],
1574
+ body: {
1575
+ required: true,
1576
+ fields: [
1577
+ {
1578
+ name: "publishable_key",
1579
+ type: "string",
1580
+ required: true,
1581
+ description: "Public key created by the service agent owner; safe to include in browser code."
1582
+ },
1583
+ {
1584
+ name: "visitor_secret",
1585
+ type: "string",
1586
+ required: false,
1587
+ description: "Secret returned by a previous anonymous issuance for this key. Omit for a new visitor; an unknown secret creates a new visitor."
1588
+ }
1589
+ ]
1590
+ }
1591
+ },
1191
1592
  {
1192
1593
  resource: "agent.embedTokens.revoke",
1193
1594
  method: "create",
@@ -1492,6 +1893,25 @@ owning account only.`
1492
1893
  type: "string",
1493
1894
  required: false,
1494
1895
  description: "Opaque pagination cursor: pass the next_page value of the previous response unchanged. Omit it for the first page. A cursor from a different query or a malformed one returns 400."
1896
+ },
1897
+ {
1898
+ name: "external_user_id",
1899
+ type: "string",
1900
+ required: false,
1901
+ description: "Filter by an exact end-user identifier (1–128 characters: A-Z, a-z, 0-9, underscore, dot, colon, at sign or hyphen). Keep this filter unchanged when following page."
1902
+ },
1903
+ {
1904
+ name: "source",
1905
+ type: "string",
1906
+ enum: [
1907
+ "kit",
1908
+ "iframe",
1909
+ "hosted",
1910
+ "api",
1911
+ "automation"
1912
+ ],
1913
+ required: false,
1914
+ description: "Filter by session origin: kit, iframe, hosted, api or automation. Keep this filter unchanged when following page."
1495
1915
  }
1496
1916
  ]
1497
1917
  },
@@ -1499,7 +1919,7 @@ owning account only.`
1499
1919
  resource: "agent.sessions",
1500
1920
  method: "create",
1501
1921
  summary: "Create session",
1502
- description: `Create a session: one conversation with an agent, running on a machine. 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 environment_id for a sandbox recipe. 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.`,
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.`,
1503
1923
  http: "POST",
1504
1924
  path: "/agent/v1/sessions",
1505
1925
  streaming: "no",
@@ -1519,7 +1939,7 @@ owning account only.`
1519
1939
  name: "environment_id",
1520
1940
  type: "string",
1521
1941
  required: false,
1522
- description: "ID of the `environment` defining the container configuration for\nthis session."
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."
1523
1943
  },
1524
1944
  {
1525
1945
  name: "budget",
@@ -1599,6 +2019,23 @@ offsets ("+08:00") and unknown names return 400. Never stored in
1599
2019
  ]
1600
2020
  }
1601
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
+ },
1602
2039
  {
1603
2040
  resource: "agent.sessions",
1604
2041
  method: "retrieve",
@@ -1872,7 +2309,7 @@ Praxis extension available only on /agent/v1, following Claude Agent SDK getCont
1872
2309
  resource: "agent.sessions.events",
1873
2310
  method: "list",
1874
2311
  summary: "List session events",
1875
- description: "Read the event history of a session as a page of events, oldest first by default (order=desc for newest first). Use it after sending a message to collect the reply, to find tool calls that wait for approval (session.status_idle with stop_reason requires_action lists their event_ids), or to audit a run; to follow a running session live use sessions.events.stream instead. Filter by types and by a created_at range on processed_at; pages hold at most 100 events (default 20) and next_page continues. A failed run emits session.error before session.status_terminated. Native history also includes user.steer, user.withdraw, system.notification, session.forked, session.goal_changed and session.goal_verification; these are not accepted by the /anthropic/v1 event-type filter.",
2312
+ description: "Read the event history of a session as a page of events, oldest first by default (order=desc for newest first). Use it after sending a message to collect the reply, to find tool calls that wait for approval or client custom tool results (session.status_idle with stop_reason requires_action lists their event_ids), or to audit a run; to follow a running session live use sessions.events.stream instead. Filter by types and by a created_at range on processed_at; pages hold at most 100 events (default 20) and next_page continues. A failed run emits session.error before session.status_terminated. Native history also includes user.steer, user.withdraw, system.notification, session.forked, session.goal_changed and session.goal_verification; these are not accepted by the /anthropic/v1 event-type filter.",
1876
2313
  http: "GET",
1877
2314
  path: "/agent/v1/sessions/{session_id}/events",
1878
2315
  streaming: "no",
@@ -1943,7 +2380,7 @@ Praxis extension available only on /agent/v1, following Claude Agent SDK getCont
1943
2380
  resource: "agent.sessions.events",
1944
2381
  method: "send",
1945
2382
  summary: "Send session events",
1946
- description: 'Send events to a session: user.message (exactly one nonempty text block), user.interrupt, user.tool_confirmation to allow or deny a pending tool call, user.steer to inject a queued user.message into a turn that is still running, and user.withdraw to retract a queued message. The response only acknowledges the inputs; read replies with sessions.events.list or sessions.events.stream. A message sent while the session waits for tool approval is queued (processed_at null) and runs in order after the approval is resolved. Archived sessions reject new messages. To approve, read a pending agent.tool_use or agent.mcp_tool_use event and send {type: "user.tool_confirmation", tool_use_id: <that event id>, result: "allow"} (or deny); include session_thread_id for a child approval. Native confirmations also accept updated_permissions, answers and annotations, which /anthropic/v1 rejects.',
2383
+ description: 'Attach optional praxis_context={items:[{name,value}]} to user.message for untrusted page context on this turn only (maximum 32 items, 4096 UTF-8 JSON bytes). /anthropic/v1 rejects this field. Send events to a session: user.message (exactly one nonempty text block), user.interrupt, user.tool_confirmation to allow or deny a pending tool call, user.custom_tool_result to return a custom tool result, user.steer to inject a queued user.message into a turn that is still running, and user.withdraw to retract a queued message. The response only acknowledges the inputs; read replies with sessions.events.list or sessions.events.stream. A message sent while the session waits for tool approval is queued (processed_at null) and runs in order after the approval is resolved. Archived sessions reject new messages. To approve, read a pending agent.tool_use or agent.mcp_tool_use event and send {type: "user.tool_confirmation", tool_use_id: <that event id>, result: "allow"} (or deny); include session_thread_id for a child approval. Native confirmations also accept updated_permissions, answers and annotations, which /anthropic/v1 rejects. Both faces accept user.custom_tool_result with custom_tool_use_id from agent.custom_tool_use.id or the requires_action stop_reason.event_ids. Unlike Anthropic, result content accepts only text blocks (omit it for an empty array). Omitted or null is_error means false. The server routes child calls by id; session_thread_id is rejected in this input. Unknown call ids return 400; duplicate results or calls no longer waiting return 409.',
1947
2384
  http: "POST",
1948
2385
  path: "/agent/v1/sessions/{session_id}/events",
1949
2386
  streaming: "no",
@@ -3113,6 +3550,27 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
3113
3550
  ],
3114
3551
  query: []
3115
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
+ },
3116
3574
  {
3117
3575
  resource: "automation.actions",
3118
3576
  method: "list",
@@ -6536,7 +6994,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6536
6994
  name: "{column}",
6537
6995
  type: "string",
6538
6996
  required: false,
6539
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
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."
6540
6998
  },
6541
6999
  {
6542
7000
  name: "and",
@@ -6584,7 +7042,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6584
7042
  name: "on_conflict",
6585
7043
  type: "string",
6586
7044
  required: false,
6587
- 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."
6588
7046
  },
6589
7047
  {
6590
7048
  name: "columns",
@@ -6598,7 +7056,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6598
7056
  resource: "database.databases.rest",
6599
7057
  method: "retrieve",
6600
7058
  summary: "Select rows",
6601
- 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. Praxis SDK/codemode methods return the body only; a page length is not a total unless you know all matches fit in that page.",
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.",
6602
7060
  http: "GET",
6603
7061
  path: "/database/v1/databases/{database_id}/rest/{table}",
6604
7062
  streaming: "no",
@@ -6624,7 +7082,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6624
7082
  name: "{column}",
6625
7083
  type: "string",
6626
7084
  required: false,
6627
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
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."
6628
7086
  },
6629
7087
  {
6630
7088
  name: "and",
@@ -6672,7 +7130,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6672
7130
  name: "on_conflict",
6673
7131
  type: "string",
6674
7132
  required: false,
6675
- 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."
6676
7134
  },
6677
7135
  {
6678
7136
  name: "columns",
@@ -6686,7 +7144,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6686
7144
  resource: "database.databases.rest",
6687
7145
  method: "head",
6688
7146
  summary: "Count rows",
6689
- 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. Praxis SDK/codemode methods return only the empty body, not the Content-Range response header; use an HTTP client when you need that header.",
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.",
6690
7148
  http: "HEAD",
6691
7149
  path: "/database/v1/databases/{database_id}/rest/{table}",
6692
7150
  streaming: "no",
@@ -6712,7 +7170,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6712
7170
  name: "{column}",
6713
7171
  type: "string",
6714
7172
  required: false,
6715
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
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."
6716
7174
  },
6717
7175
  {
6718
7176
  name: "and",
@@ -6760,7 +7218,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6760
7218
  name: "on_conflict",
6761
7219
  type: "string",
6762
7220
  required: false,
6763
- 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."
6764
7222
  },
6765
7223
  {
6766
7224
  name: "columns",
@@ -6800,7 +7258,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6800
7258
  name: "{column}",
6801
7259
  type: "string",
6802
7260
  required: false,
6803
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
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."
6804
7262
  },
6805
7263
  {
6806
7264
  name: "and",
@@ -6848,7 +7306,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6848
7306
  name: "on_conflict",
6849
7307
  type: "string",
6850
7308
  required: false,
6851
- 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."
6852
7310
  },
6853
7311
  {
6854
7312
  name: "columns",
@@ -6868,7 +7326,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6868
7326
  summary: "Insert rows",
6869
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.
6870
7328
  Rows are filled to the union of their keys with null; send Prefer: missing=default to use field defaults for missing keys.
6871
- 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.`,
6872
7330
  http: "POST",
6873
7331
  path: "/database/v1/databases/{database_id}/rest/{table}",
6874
7332
  streaming: "no",
@@ -6894,7 +7352,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6894
7352
  name: "{column}",
6895
7353
  type: "string",
6896
7354
  required: false,
6897
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
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."
6898
7356
  },
6899
7357
  {
6900
7358
  name: "and",
@@ -6942,7 +7400,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6942
7400
  name: "on_conflict",
6943
7401
  type: "string",
6944
7402
  required: false,
6945
- 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."
6946
7404
  },
6947
7405
  {
6948
7406
  name: "columns",
@@ -6994,7 +7452,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6994
7452
  resource: "database.databases.tables",
6995
7453
  method: "create",
6996
7454
  summary: "Create table",
6997
- 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. 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.",
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.',
6998
7456
  http: "POST",
6999
7457
  path: "/database/v1/databases/{database_id}/tables",
7000
7458
  streaming: "no",
@@ -7115,7 +7573,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
7115
7573
  resource: "database.databases.tables.fields",
7116
7574
  method: "create",
7117
7575
  summary: "Add field",
7118
- 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. Scalar fields are indexed by default, while 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.",
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.',
7119
7577
  http: "POST",
7120
7578
  path: "/database/v1/databases/{database_id}/tables/{table}/fields",
7121
7579
  streaming: "no",
@@ -7285,7 +7743,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
7285
7743
  resource: "file.files",
7286
7744
  method: "create",
7287
7745
  summary: "Upload file",
7288
- description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 104857600 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. OpenAI Uploads chunking is not supported. 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.',
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.',
7289
7747
  http: "POST",
7290
7748
  path: "/file/v1/files",
7291
7749
  streaming: "no",
@@ -7297,10 +7755,119 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
7297
7755
  required: true,
7298
7756
  fields: [
7299
7757
  {
7300
- name: "file",
7758
+ name: "file",
7759
+ type: "string",
7760
+ required: true,
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."
7762
+ },
7763
+ {
7764
+ name: "purpose",
7765
+ type: "string",
7766
+ enum: [
7767
+ "user_data",
7768
+ "assistants",
7769
+ "vision"
7770
+ ],
7771
+ required: true,
7772
+ description: "Purpose label stored with the file: user_data, assistants or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
7773
+ },
7774
+ {
7775
+ name: "expires_after",
7776
+ type: "object",
7777
+ required: false,
7778
+ description: "Optional expiry relative to created_at. Files without an expiry persist until deleted."
7779
+ },
7780
+ {
7781
+ name: "praxis",
7782
+ type: "object",
7783
+ required: false,
7784
+ description: "Own-face extensions. Use at most one expiry setting."
7785
+ }
7786
+ ]
7787
+ }
7788
+ },
7789
+ {
7790
+ resource: "file.files",
7791
+ method: "delete",
7792
+ summary: "Delete file",
7793
+ description: "Delete a tenant-owned file. New metadata/content reads return not found. Already-authorized downloads may finish.",
7794
+ http: "DELETE",
7795
+ path: "/file/v1/files/{file_id}",
7796
+ streaming: "no",
7797
+ pagination: false,
7798
+ pathParams: [
7799
+ {
7800
+ name: "file_id",
7801
+ sdkName: "file_id"
7802
+ }
7803
+ ],
7804
+ query: []
7805
+ },
7806
+ {
7807
+ resource: "file.files",
7808
+ method: "retrieve",
7809
+ summary: "Retrieve file",
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.",
7811
+ http: "GET",
7812
+ path: "/file/v1/files/{file_id}",
7813
+ streaming: "no",
7814
+ pagination: false,
7815
+ pathParams: [
7816
+ {
7817
+ name: "file_id",
7818
+ sdkName: "file_id"
7819
+ }
7820
+ ],
7821
+ query: []
7822
+ },
7823
+ {
7824
+ resource: "file.files",
7825
+ method: "retrieveContent",
7826
+ summary: "Retrieve file content",
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.",
7828
+ http: "GET",
7829
+ path: "/file/v1/files/{file_id}/content",
7830
+ streaming: "no",
7831
+ pagination: false,
7832
+ pathParams: [
7833
+ {
7834
+ name: "file_id",
7835
+ sdkName: "file_id"
7836
+ }
7837
+ ],
7838
+ query: []
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, uploads accept at most 2 GiB (2147483648 bytes) and only user_data, assistants and vision purposes. 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 2147483648 (2 GiB); 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",
7301
7868
  type: "string",
7302
7869
  required: true,
7303
- description: "File bytes in one multipart file part, not a filename or file ID. The file must be nonempty and at most 104857600 bytes; its content determines the MIME type."
7870
+ description: "Declared MIME type; validated against the assembled content."
7304
7871
  },
7305
7872
  {
7306
7873
  name: "purpose",
@@ -7311,73 +7878,110 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
7311
7878
  "vision"
7312
7879
  ],
7313
7880
  required: true,
7314
- description: "Purpose label stored with the file: user_data, assistants or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
7881
+ description: "Use user_data for conversation attachments, assistants for assistant files, or vision for PNG, JPEG, GIF and WebP images."
7315
7882
  },
7316
7883
  {
7317
7884
  name: "expires_after",
7318
7885
  type: "object",
7319
7886
  required: false,
7320
- description: "Optional expiry relative to created_at. Files without an expiry persist until deleted."
7887
+ description: "Optional expiry policy for the resulting file; omission retains the file until deletion."
7321
7888
  },
7322
7889
  {
7323
- name: "praxis",
7324
- type: "object",
7890
+ name: "part_size",
7891
+ type: "integer",
7325
7892
  required: false,
7326
- description: "Own-face extensions. Use at most one expiry setting."
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."
7327
7894
  }
7328
7895
  ]
7329
7896
  }
7330
7897
  },
7331
7898
  {
7332
- resource: "file.files",
7333
- method: "delete",
7334
- summary: "Delete file",
7335
- description: "Delete a tenant-owned file. New metadata/content reads return not found. Already-authorized downloads may finish.",
7336
- http: "DELETE",
7337
- path: "/file/v1/files/{file_id}",
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",
7338
7905
  streaming: "no",
7339
7906
  pagination: false,
7340
7907
  pathParams: [
7341
7908
  {
7342
- name: "file_id",
7343
- sdkName: "file_id"
7909
+ name: "upload_id",
7910
+ sdkName: "upload_id"
7344
7911
  }
7345
7912
  ],
7346
7913
  query: []
7347
7914
  },
7348
7915
  {
7349
- resource: "file.files",
7350
- method: "retrieve",
7351
- summary: "Retrieve file",
7352
- description: "Retrieve metadata for a live file owned by your tenant. Use its file_dp_ ID from upload or list. Missing, deleted, expired and other-tenant files return 404; use the content endpoint to download the bytes.",
7353
- http: "GET",
7354
- path: "/file/v1/files/{file_id}",
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",
7355
7922
  streaming: "no",
7356
7923
  pagination: false,
7357
7924
  pathParams: [
7358
7925
  {
7359
- name: "file_id",
7360
- sdkName: "file_id"
7926
+ name: "upload_id",
7927
+ sdkName: "upload_id"
7361
7928
  }
7362
7929
  ],
7363
- query: []
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
+ }
7364
7949
  },
7365
7950
  {
7366
- resource: "file.files",
7367
- method: "retrieveContent",
7368
- summary: "Retrieve file content",
7369
- description: "Download the original bytes of a live file owned by your tenant. Supply its file_dp_ 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.",
7370
- http: "GET",
7371
- path: "/file/v1/files/{file_id}/content",
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",
7372
7957
  streaming: "no",
7373
7958
  pagination: false,
7959
+ multipart: true,
7374
7960
  pathParams: [
7375
7961
  {
7376
- name: "file_id",
7377
- sdkName: "file_id"
7962
+ name: "upload_id",
7963
+ sdkName: "upload_id"
7378
7964
  }
7379
7965
  ],
7380
- query: []
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
+ }
7381
7985
  },
7382
7986
  {
7383
7987
  resource: "knowledge.vectorStores",
@@ -11680,15 +12284,8 @@ for more details.`
11680
12284
  {
11681
12285
  name: "phase",
11682
12286
  type: "string",
11683
- enum: [
11684
- "open",
11685
- "awaiting_customer",
11686
- "in_progress",
11687
- "resolved",
11688
- "closed"
11689
- ],
11690
12287
  required: false,
11691
- description: "Only feedback in this phase: open, awaiting_customer, in_progress, resolved or closed; see the phase field of a feedback for what each means."
12288
+ description: "Only feedback in these phases: a comma-separated list of open, awaiting_customer, in_progress, resolved or closed, for example open,in_progress; see the phase field of a feedback for what each means."
11692
12289
  },
11693
12290
  {
11694
12291
  name: "query",
@@ -11728,7 +12325,7 @@ for more details.`
11728
12325
  name: "message",
11729
12326
  type: "string",
11730
12327
  required: true,
11731
- description: "Problem description and original error text; at most 4096 Unicode code points."
12328
+ description: "Problem description, at most 4096 Unicode code points; may be empty only when contexts.praxis.error.message is a non-empty string."
11732
12329
  },
11733
12330
  {
11734
12331
  name: "contact_email",
@@ -11798,6 +12395,18 @@ for more details.`
11798
12395
  ]
11799
12396
  }
11800
12397
  },
12398
+ {
12399
+ resource: "organization.feedback.counts",
12400
+ method: "list",
12401
+ summary: "Count your organization's feedback by phase",
12402
+ description: "How many of your organization's feedback are in each phase, for status tabs. Counts never include another organization's feedback.",
12403
+ http: "GET",
12404
+ path: "/organization/v1/feedback/counts",
12405
+ streaming: "no",
12406
+ pagination: false,
12407
+ pathParams: [],
12408
+ query: []
12409
+ },
11801
12410
  {
11802
12411
  resource: "organization.feedback",
11803
12412
  method: "retrieve",
@@ -14226,59 +14835,285 @@ for more details.`
14226
14835
  name: "vault_id",
14227
14836
  sdkName: "vault_id"
14228
14837
  }
14229
- ],
14230
- query: [],
14231
- body: {
14232
- required: true,
14233
- fields: [
14234
- {
14235
- name: "lines",
14236
- type: "array",
14237
- itemType: "object",
14238
- required: false,
14239
- description: "Entries to import, each succeeding or failing independently. Supply 1–50 entries and omit dotenv."
14240
- },
14241
- {
14242
- name: "dotenv",
14243
- type: "string",
14244
- required: false,
14245
- description: "KEY=VALUE text to import instead of lines. Blank lines and comments are ignored; export prefixes and single- or double-quoted values are supported. Supply 1–50 parsed entries; multiline quoted values are unsupported."
14246
- },
14247
- {
14248
- name: "allowed_hosts",
14249
- type: "array",
14250
- itemType: "string",
14251
- required: false,
14252
- description: "Default hosts for newly created secrets whose entry omits allowed_hosts. Never changes the hosts of an existing secret; use per-line allowed_hosts for that. Uses the same host rules as Create secret."
14253
- }
14254
- ]
14838
+ ],
14839
+ query: [],
14840
+ body: {
14841
+ required: true,
14842
+ fields: [
14843
+ {
14844
+ name: "lines",
14845
+ type: "array",
14846
+ itemType: "object",
14847
+ required: false,
14848
+ description: "Entries to import, each succeeding or failing independently. Supply 1–50 entries and omit dotenv."
14849
+ },
14850
+ {
14851
+ name: "dotenv",
14852
+ type: "string",
14853
+ required: false,
14854
+ description: "KEY=VALUE text to import instead of lines. Blank lines and comments are ignored; export prefixes and single- or double-quoted values are supported. Supply 1–50 parsed entries; multiline quoted values are unsupported."
14855
+ },
14856
+ {
14857
+ name: "allowed_hosts",
14858
+ type: "array",
14859
+ itemType: "string",
14860
+ required: false,
14861
+ description: "Default hosts for newly created secrets whose entry omits allowed_hosts. Never changes the hosts of an existing secret; use per-line allowed_hosts for that. Uses the same host rules as Create secret."
14862
+ }
14863
+ ]
14864
+ }
14865
+ },
14866
+ {
14867
+ resource: "vault.vaults",
14868
+ method: "check",
14869
+ summary: "Check vaults",
14870
+ description: "Check the availability of each supplied vault ID in request order. Missing, malformed and other accounts' IDs all return not_found; duplicate IDs are preserved.",
14871
+ http: "POST",
14872
+ path: "/vault/v1/vaults:check",
14873
+ streaming: "no",
14874
+ pagination: false,
14875
+ pathParams: [],
14876
+ query: [],
14877
+ body: {
14878
+ required: true,
14879
+ fields: [
14880
+ {
14881
+ name: "vault_ids",
14882
+ type: "array",
14883
+ itemType: "string",
14884
+ required: true,
14885
+ description: "Vault IDs to check in request order. Invalid or inaccessible IDs yield not_found; duplicates are preserved and an empty array is allowed."
14886
+ }
14887
+ ]
14888
+ }
14889
+ }
14890
+ ];
14891
+
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
+ };
14913
+ }
14914
+
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;
14255
15098
  }
14256
- },
14257
- {
14258
- resource: "vault.vaults",
14259
- method: "check",
14260
- summary: "Check vaults",
14261
- description: "Check the availability of each supplied vault ID in request order. Missing, malformed and other accounts' IDs all return not_found; duplicate IDs are preserved.",
14262
- http: "POST",
14263
- path: "/vault/v1/vaults:check",
14264
- streaming: "no",
14265
- pagination: false,
14266
- pathParams: [],
14267
- query: [],
14268
- body: {
14269
- required: true,
14270
- fields: [
14271
- {
14272
- name: "vault_ids",
14273
- type: "array",
14274
- itemType: "string",
14275
- required: true,
14276
- description: "Vault IDs to check in request order. Invalid or inaccessible IDs yield not_found; duplicates are preserved and an empty array is allowed."
14277
- }
14278
- ]
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(() => {});
14279
15109
  }
15110
+ if (options.signal?.aborted)
15111
+ throw options.signal.reason;
15112
+ throw error;
15113
+ } finally {
15114
+ options.signal?.removeEventListener("abort", abort);
14280
15115
  }
14281
- ];
15116
+ }
14282
15117
 
14283
15118
  // ../../packages/sdk/typescript/src/core/multipart.ts
14284
15119
  function multipartBodySerializer(body) {
@@ -14347,9 +15182,9 @@ function createSseClient({
14347
15182
  ...options
14348
15183
  }) {
14349
15184
  let lastEventId;
14350
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
15185
+ const sleep2 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
14351
15186
  const createStream = async function* () {
14352
- let retryDelay = sseDefaultRetryDelay ?? 3000;
15187
+ let retryDelay2 = sseDefaultRetryDelay ?? 3000;
14353
15188
  let attempt = 0;
14354
15189
  const signal = options.signal ?? new AbortController().signal;
14355
15190
  while (true) {
@@ -14413,7 +15248,7 @@ function createSseClient({
14413
15248
  } else if (line.startsWith("retry:")) {
14414
15249
  const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
14415
15250
  if (!Number.isNaN(parsed)) {
14416
- retryDelay = parsed;
15251
+ retryDelay2 = parsed;
14417
15252
  }
14418
15253
  }
14419
15254
  }
@@ -14441,7 +15276,7 @@ function createSseClient({
14441
15276
  data,
14442
15277
  event: eventName,
14443
15278
  id: lastEventId,
14444
- retry: retryDelay
15279
+ retry: retryDelay2
14445
15280
  });
14446
15281
  if (dataLines.length) {
14447
15282
  yield data;
@@ -14458,8 +15293,8 @@ function createSseClient({
14458
15293
  if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) {
14459
15294
  break;
14460
15295
  }
14461
- const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
14462
- await sleep(backoff);
15296
+ const backoff = Math.min(retryDelay2 * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000);
15297
+ await sleep2(backoff);
14463
15298
  }
14464
15299
  }
14465
15300
  };
@@ -15102,6 +15937,19 @@ var createClient = (config = {}) => {
15102
15937
  var client = createClient(createConfig({ baseUrl: "https://api.deepraxis.com" }));
15103
15938
 
15104
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
+ });
15105
15953
  var deleteRunFeedback = (options) => (options.client ?? client).delete({
15106
15954
  security: [{
15107
15955
  key: "BearerAuth",
@@ -15132,6 +15980,113 @@ var setRunFeedback = (options) => (options.client ?? client).post({
15132
15980
  ...options.headers
15133
15981
  }
15134
15982
  });
15983
+ var listEndUsers = (options) => (options.client ?? client).get({
15984
+ security: [{
15985
+ key: "BearerAuth",
15986
+ scheme: "bearer",
15987
+ type: "http"
15988
+ }, {
15989
+ key: "ApiKeyAuth",
15990
+ name: "X-API-Key",
15991
+ type: "apiKey"
15992
+ }],
15993
+ url: "/agent/v1/agents/{agent_id}/end_users",
15994
+ ...options
15995
+ });
15996
+ var deleteEndUser = (options) => (options.client ?? client).delete({
15997
+ security: [{
15998
+ key: "BearerAuth",
15999
+ scheme: "bearer",
16000
+ type: "http"
16001
+ }, {
16002
+ key: "ApiKeyAuth",
16003
+ name: "X-API-Key",
16004
+ type: "apiKey"
16005
+ }],
16006
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
16007
+ ...options
16008
+ });
16009
+ var getEndUser = (options) => (options.client ?? client).get({
16010
+ security: [{
16011
+ key: "BearerAuth",
16012
+ scheme: "bearer",
16013
+ type: "http"
16014
+ }, {
16015
+ key: "ApiKeyAuth",
16016
+ name: "X-API-Key",
16017
+ type: "apiKey"
16018
+ }],
16019
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
16020
+ ...options
16021
+ });
16022
+ var getEndUserDeletion = (options) => (options.client ?? client).get({
16023
+ security: [{
16024
+ key: "BearerAuth",
16025
+ scheme: "bearer",
16026
+ type: "http"
16027
+ }, {
16028
+ key: "ApiKeyAuth",
16029
+ name: "X-API-Key",
16030
+ type: "apiKey"
16031
+ }],
16032
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/deletion",
16033
+ ...options
16034
+ });
16035
+ var revokeEndUserTokens = (options) => (options.client ?? client).post({
16036
+ security: [{
16037
+ key: "BearerAuth",
16038
+ scheme: "bearer",
16039
+ type: "http"
16040
+ }, {
16041
+ key: "ApiKeyAuth",
16042
+ name: "X-API-Key",
16043
+ type: "apiKey"
16044
+ }],
16045
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/revoke_tokens",
16046
+ ...options
16047
+ });
16048
+ var blockEndUser = (options) => (options.client ?? client).post({
16049
+ security: [{
16050
+ key: "BearerAuth",
16051
+ scheme: "bearer",
16052
+ type: "http"
16053
+ }, {
16054
+ key: "ApiKeyAuth",
16055
+ name: "X-API-Key",
16056
+ type: "apiKey"
16057
+ }],
16058
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/block",
16059
+ ...options
16060
+ });
16061
+ var unblockEndUser = (options) => (options.client ?? client).post({
16062
+ security: [{
16063
+ key: "BearerAuth",
16064
+ scheme: "bearer",
16065
+ type: "http"
16066
+ }, {
16067
+ key: "ApiKeyAuth",
16068
+ name: "X-API-Key",
16069
+ type: "apiKey"
16070
+ }],
16071
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/unblock",
16072
+ ...options
16073
+ });
16074
+ var exchangeEmbedCode = (options) => (options.client ?? client).post({
16075
+ url: "/agent/v1/embed/exchange",
16076
+ ...options,
16077
+ headers: {
16078
+ "Content-Type": "application/json",
16079
+ ...options.headers
16080
+ }
16081
+ });
16082
+ var createAnonymousEmbedToken = (options) => (options.client ?? client).post({
16083
+ url: "/agent/v1/embed_tokens/anonymous",
16084
+ ...options,
16085
+ headers: {
16086
+ "Content-Type": "application/json",
16087
+ ...options.headers
16088
+ }
16089
+ });
15135
16090
  var listEmbedTokens = (options) => (options?.client ?? client).get({
15136
16091
  security: [{
15137
16092
  key: "BearerAuth",
@@ -15316,6 +16271,36 @@ var connectComputer = (options) => (options.client ?? client).post({
15316
16271
  type: "apiKey"
15317
16272
  }],
15318
16273
  url: "/agent/v1/computers/{computer_id}/connect",
16274
+ ...options,
16275
+ headers: {
16276
+ "Content-Type": "application/json",
16277
+ ...options.headers
16278
+ }
16279
+ });
16280
+ var renewComputerLease = (options) => (options.client ?? client).post({
16281
+ security: [{
16282
+ key: "BearerAuth",
16283
+ scheme: "bearer",
16284
+ type: "http"
16285
+ }, {
16286
+ key: "ApiKeyAuth",
16287
+ name: "X-API-Key",
16288
+ type: "apiKey"
16289
+ }],
16290
+ url: "/agent/v1/computers/{computer_id}/leases/{lease_id}/renew",
16291
+ ...options
16292
+ });
16293
+ var releaseComputerLease = (options) => (options.client ?? client).delete({
16294
+ security: [{
16295
+ key: "BearerAuth",
16296
+ scheme: "bearer",
16297
+ type: "http"
16298
+ }, {
16299
+ key: "ApiKeyAuth",
16300
+ name: "X-API-Key",
16301
+ type: "apiKey"
16302
+ }],
16303
+ url: "/agent/v1/computers/{computer_id}/leases/{lease_id}",
15319
16304
  ...options
15320
16305
  });
15321
16306
  var listToolsets = (options) => (options?.client ?? client).get({
@@ -15443,6 +16428,15 @@ var listSessionCompactions = (options) => (options.client ?? client).get({
15443
16428
  url: "/agent/v1/sessions/{session_id}/compactions",
15444
16429
  ...options
15445
16430
  });
16431
+ var getEmbedAppearance = (options) => (options?.client ?? client).get({
16432
+ security: [{
16433
+ key: "BearerAuth",
16434
+ scheme: "bearer",
16435
+ type: "http"
16436
+ }, { name: "Praxis-Publishable-Key", type: "apiKey" }],
16437
+ url: "/agent/v1/embed/appearance",
16438
+ ...options
16439
+ });
15446
16440
  var createAudioSpeech = (options) => (options.client ?? client).post({
15447
16441
  security: [{
15448
16442
  key: "BearerAuth",
@@ -15698,30 +16692,79 @@ var fileDeleteFile = (options) => (options.client ?? client).delete({
15698
16692
  url: "/file/v1/files/{file_id}",
15699
16693
  ...options
15700
16694
  });
15701
- var fileRetrieveFile = (options) => (options.client ?? client).get({
16695
+ var fileRetrieveFile = (options) => (options.client ?? client).get({
16696
+ security: [{
16697
+ key: "BearerAuth",
16698
+ scheme: "bearer",
16699
+ type: "http"
16700
+ }, {
16701
+ key: "ApiKeyAuth",
16702
+ name: "X-API-Key",
16703
+ type: "apiKey"
16704
+ }],
16705
+ url: "/file/v1/files/{file_id}",
16706
+ ...options
16707
+ });
16708
+ var fileRetrieveFileContent = (options) => (options.client ?? client).get({
16709
+ security: [{
16710
+ key: "BearerAuth",
16711
+ scheme: "bearer",
16712
+ type: "http"
16713
+ }, {
16714
+ key: "ApiKeyAuth",
16715
+ name: "X-API-Key",
16716
+ type: "apiKey"
16717
+ }],
16718
+ url: "/file/v1/files/{file_id}/content",
16719
+ ...options
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({
15702
16749
  security: [{
15703
16750
  key: "BearerAuth",
15704
16751
  scheme: "bearer",
15705
16752
  type: "http"
15706
- }, {
15707
- key: "ApiKeyAuth",
15708
- name: "X-API-Key",
15709
- type: "apiKey"
15710
16753
  }],
15711
- url: "/file/v1/files/{file_id}",
15712
- ...options
16754
+ url: "/file/v1/uploads/{upload_id}/complete",
16755
+ ...options,
16756
+ headers: {
16757
+ "Content-Type": "application/json",
16758
+ ...options.headers
16759
+ }
15713
16760
  });
15714
- var fileRetrieveFileContent = (options) => (options.client ?? client).get({
16761
+ var fileCancelUpload = (options) => (options.client ?? client).post({
15715
16762
  security: [{
15716
16763
  key: "BearerAuth",
15717
16764
  scheme: "bearer",
15718
16765
  type: "http"
15719
- }, {
15720
- key: "ApiKeyAuth",
15721
- name: "X-API-Key",
15722
- type: "apiKey"
15723
16766
  }],
15724
- url: "/file/v1/files/{file_id}/content",
16767
+ url: "/file/v1/uploads/{upload_id}/cancel",
15725
16768
  ...options
15726
16769
  });
15727
16770
  var healthCheck = (options) => (options?.client ?? client).get({ url: "/meta/v1/health", ...options });
@@ -16211,6 +17254,19 @@ var createOrganizationFeedback = (options) => (options.client ?? client).post({
16211
17254
  ...options.headers
16212
17255
  }
16213
17256
  });
17257
+ var getOrganizationFeedbackCounts = (options) => (options?.client ?? client).get({
17258
+ security: [{
17259
+ key: "BearerAuth",
17260
+ scheme: "bearer",
17261
+ type: "http"
17262
+ }, {
17263
+ key: "ApiKeyAuth",
17264
+ name: "X-API-Key",
17265
+ type: "apiKey"
17266
+ }],
17267
+ url: "/organization/v1/feedback/counts",
17268
+ ...options
17269
+ });
16214
17270
  var getOrganizationFeedback = (options) => (options.client ?? client).get({
16215
17271
  security: [{
16216
17272
  key: "BearerAuth",
@@ -16546,7 +17602,7 @@ var runSandboxCommand = (options) => (options.client ?? client).post({
16546
17602
  ...options.headers
16547
17603
  }
16548
17604
  });
16549
- var agentsList = (options) => (options?.client ?? client).get({
17605
+ var sessionsDelete = (options) => (options.client ?? client).delete({
16550
17606
  security: [{
16551
17607
  key: "BearerAuth",
16552
17608
  scheme: "bearer",
@@ -16556,10 +17612,10 @@ var agentsList = (options) => (options?.client ?? client).get({
16556
17612
  name: "X-API-Key",
16557
17613
  type: "apiKey"
16558
17614
  }],
16559
- url: "/agent/v1/agents",
17615
+ url: "/agent/v1/sessions/{session_id}",
16560
17616
  ...options
16561
17617
  });
16562
- var agentsCreate = (options) => (options.client ?? client).post({
17618
+ var sessionsRetrieve = (options) => (options.client ?? client).get({
16563
17619
  security: [{
16564
17620
  key: "BearerAuth",
16565
17621
  scheme: "bearer",
@@ -16569,14 +17625,27 @@ var agentsCreate = (options) => (options.client ?? client).post({
16569
17625
  name: "X-API-Key",
16570
17626
  type: "apiKey"
16571
17627
  }],
16572
- url: "/agent/v1/agents",
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}",
16573
17642
  ...options,
16574
17643
  headers: {
16575
17644
  "Content-Type": "application/json",
16576
17645
  ...options.headers
16577
17646
  }
16578
17647
  });
16579
- var agentsRetrieve = (options) => (options.client ?? client).get({
17648
+ var agentsList = (options) => (options?.client ?? client).get({
16580
17649
  security: [{
16581
17650
  key: "BearerAuth",
16582
17651
  scheme: "bearer",
@@ -16586,10 +17655,10 @@ var agentsRetrieve = (options) => (options.client ?? client).get({
16586
17655
  name: "X-API-Key",
16587
17656
  type: "apiKey"
16588
17657
  }],
16589
- url: "/agent/v1/agents/{agent_id}",
17658
+ url: "/agent/v1/agents",
16590
17659
  ...options
16591
17660
  });
16592
- var agentsUpdate = (options) => (options.client ?? client).post({
17661
+ var agentsCreate = (options) => (options.client ?? client).post({
16593
17662
  security: [{
16594
17663
  key: "BearerAuth",
16595
17664
  scheme: "bearer",
@@ -16599,14 +17668,14 @@ var agentsUpdate = (options) => (options.client ?? client).post({
16599
17668
  name: "X-API-Key",
16600
17669
  type: "apiKey"
16601
17670
  }],
16602
- url: "/agent/v1/agents/{agent_id}",
17671
+ url: "/agent/v1/agents",
16603
17672
  ...options,
16604
17673
  headers: {
16605
17674
  "Content-Type": "application/json",
16606
17675
  ...options.headers
16607
17676
  }
16608
17677
  });
16609
- var agentsArchive = (options) => (options.client ?? client).post({
17678
+ var agentsRetrieve = (options) => (options.client ?? client).get({
16610
17679
  security: [{
16611
17680
  key: "BearerAuth",
16612
17681
  scheme: "bearer",
@@ -16616,10 +17685,10 @@ var agentsArchive = (options) => (options.client ?? client).post({
16616
17685
  name: "X-API-Key",
16617
17686
  type: "apiKey"
16618
17687
  }],
16619
- url: "/agent/v1/agents/{agent_id}/archive",
17688
+ url: "/agent/v1/agents/{agent_id}",
16620
17689
  ...options
16621
17690
  });
16622
- var agentsVersionsList = (options) => (options.client ?? client).get({
17691
+ var agentsUpdate = (options) => (options.client ?? client).post({
16623
17692
  security: [{
16624
17693
  key: "BearerAuth",
16625
17694
  scheme: "bearer",
@@ -16629,10 +17698,14 @@ var agentsVersionsList = (options) => (options.client ?? client).get({
16629
17698
  name: "X-API-Key",
16630
17699
  type: "apiKey"
16631
17700
  }],
16632
- url: "/agent/v1/agents/{agent_id}/versions",
16633
- ...options
17701
+ url: "/agent/v1/agents/{agent_id}",
17702
+ ...options,
17703
+ headers: {
17704
+ "Content-Type": "application/json",
17705
+ ...options.headers
17706
+ }
16634
17707
  });
16635
- var sessionsList = (options) => (options?.client ?? client).get({
17708
+ var agentsArchive = (options) => (options.client ?? client).post({
16636
17709
  security: [{
16637
17710
  key: "BearerAuth",
16638
17711
  scheme: "bearer",
@@ -16642,10 +17715,10 @@ var sessionsList = (options) => (options?.client ?? client).get({
16642
17715
  name: "X-API-Key",
16643
17716
  type: "apiKey"
16644
17717
  }],
16645
- url: "/agent/v1/sessions",
17718
+ url: "/agent/v1/agents/{agent_id}/archive",
16646
17719
  ...options
16647
17720
  });
16648
- var sessionsCreate = (options) => (options.client ?? client).post({
17721
+ var agentsVersionsList = (options) => (options.client ?? client).get({
16649
17722
  security: [{
16650
17723
  key: "BearerAuth",
16651
17724
  scheme: "bearer",
@@ -16655,14 +17728,10 @@ var sessionsCreate = (options) => (options.client ?? client).post({
16655
17728
  name: "X-API-Key",
16656
17729
  type: "apiKey"
16657
17730
  }],
16658
- url: "/agent/v1/sessions",
16659
- ...options,
16660
- headers: {
16661
- "Content-Type": "application/json",
16662
- ...options.headers
16663
- }
17731
+ url: "/agent/v1/agents/{agent_id}/versions",
17732
+ ...options
16664
17733
  });
16665
- var sessionsRetrieve = (options) => (options.client ?? client).get({
17734
+ var sessionsList = (options) => (options?.client ?? client).get({
16666
17735
  security: [{
16667
17736
  key: "BearerAuth",
16668
17737
  scheme: "bearer",
@@ -16672,10 +17741,10 @@ var sessionsRetrieve = (options) => (options.client ?? client).get({
16672
17741
  name: "X-API-Key",
16673
17742
  type: "apiKey"
16674
17743
  }],
16675
- url: "/agent/v1/sessions/{session_id}",
17744
+ url: "/agent/v1/sessions",
16676
17745
  ...options
16677
17746
  });
16678
- var sessionsUpdate = (options) => (options.client ?? client).post({
17747
+ var sessionsCreate = (options) => (options.client ?? client).post({
16679
17748
  security: [{
16680
17749
  key: "BearerAuth",
16681
17750
  scheme: "bearer",
@@ -16685,7 +17754,7 @@ var sessionsUpdate = (options) => (options.client ?? client).post({
16685
17754
  name: "X-API-Key",
16686
17755
  type: "apiKey"
16687
17756
  }],
16688
- url: "/agent/v1/sessions/{session_id}",
17757
+ url: "/agent/v1/sessions",
16689
17758
  ...options,
16690
17759
  headers: {
16691
17760
  "Content-Type": "application/json",
@@ -17186,6 +18255,15 @@ var applicationCreateVersion = (options) => (options.client ?? client).post({
17186
18255
  ...options.headers
17187
18256
  }
17188
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
+ });
17189
18267
  var applicationGetVersion = (options) => (options.client ?? client).get({
17190
18268
  security: [{
17191
18269
  key: "application-bearerAuth",
@@ -20006,8 +21084,26 @@ function createAgent(transport) {
20006
21084
  agents: {
20007
21085
  archive: bind(transport, agentsArchive),
20008
21086
  create: bind(transport, agentsCreate),
21087
+ endUsers: {
21088
+ block: {
21089
+ create: bind(transport, blockEndUser)
21090
+ },
21091
+ delete: bind(transport, deleteEndUser),
21092
+ list: bind(transport, listEndUsers),
21093
+ retrieve: bind(transport, getEndUser),
21094
+ retrieveDeletion: bind(transport, getEndUserDeletion),
21095
+ revokeTokens: {
21096
+ create: bind(transport, revokeEndUserTokens)
21097
+ },
21098
+ unblock: {
21099
+ create: bind(transport, unblockEndUser)
21100
+ }
21101
+ },
20009
21102
  list: bind(transport, agentsList),
20010
21103
  retrieve: bind(transport, agentsRetrieve),
21104
+ unarchive: {
21105
+ create: bind(transport, unarchiveAgent)
21106
+ },
20011
21107
  update: bind(transport, agentsUpdate),
20012
21108
  versions: {
20013
21109
  list: bind(transport, agentsVersionsList)
@@ -20025,6 +21121,12 @@ function createAgent(transport) {
20025
21121
  list: bind(transport, computersFilesList),
20026
21122
  retrieveContent: bind(transport, computersFilesContent)
20027
21123
  },
21124
+ leases: {
21125
+ delete: bind(transport, releaseComputerLease),
21126
+ renew: {
21127
+ create: bind(transport, renewComputerLease)
21128
+ }
21129
+ },
20028
21130
  list: bind(transport, computersList),
20029
21131
  retrieve: bind(transport, computersRetrieve),
20030
21132
  update: bind(transport, computersUpdate)
@@ -20047,7 +21149,16 @@ function createAgent(transport) {
20047
21149
  },
20048
21150
  update: bind(transport, deploymentsUpdate)
20049
21151
  },
21152
+ embed: {
21153
+ exchange: {
21154
+ create: bind(transport, exchangeEmbedCode)
21155
+ },
21156
+ retrieveAppearance: bind(transport, getEmbedAppearance)
21157
+ },
20050
21158
  embedTokens: {
21159
+ anonymous: {
21160
+ create: bind(transport, createAnonymousEmbedToken)
21161
+ },
20051
21162
  create: bind(transport, createEmbedToken),
20052
21163
  list: bind(transport, listEmbedTokens),
20053
21164
  revoke: {
@@ -20073,6 +21184,7 @@ function createAgent(transport) {
20073
21184
  list: bind(transport, listSessionCompactions)
20074
21185
  },
20075
21186
  create: bind(transport, sessionsCreate),
21187
+ delete: bind(transport, sessionsDelete),
20076
21188
  events: {
20077
21189
  list: bind(transport, sessionsEventsList),
20078
21190
  send: bind(transport, sessionsEventsSend),
@@ -20154,6 +21266,9 @@ function createApplication(transport) {
20154
21266
  },
20155
21267
  update: bind(transport, applicationUpdateWorker),
20156
21268
  versions: {
21269
+ assets: {
21270
+ retrieveManifest: bind(transport, applicationGetVersionAssetManifest)
21271
+ },
20157
21272
  create: bind(transport, applicationCreateVersion),
20158
21273
  list: bindPage(transport, applicationListVersions),
20159
21274
  retrieve: bind(transport, applicationGetVersion)
@@ -20361,6 +21476,14 @@ function createFile(transport) {
20361
21476
  list: bind(transport, fileListFiles),
20362
21477
  retrieve: bind(transport, fileRetrieveFile),
20363
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
+ }
20364
21487
  }
20365
21488
  };
20366
21489
  }
@@ -20569,6 +21692,9 @@ function createOrganization(transport) {
20569
21692
  retrieve: bind(transport, getOrganizationEvent)
20570
21693
  },
20571
21694
  feedback: {
21695
+ counts: {
21696
+ list: bind(transport, getOrganizationFeedbackCounts)
21697
+ },
20572
21698
  create: bind(transport, createOrganizationFeedback),
20573
21699
  list: bind(transport, listOrganizationFeedback),
20574
21700
  messages: {
@@ -20728,132 +21854,6 @@ var resourceFactories = {
20728
21854
  vault: createVault
20729
21855
  };
20730
21856
 
20731
- // ../../packages/sdk/typescript/src/core/errors.ts
20732
- function problemFrom(status, headers, body, statusText) {
20733
- const value = body && typeof body === "object" ? body : {};
20734
- const nested = value.error && typeof value.error === "object" ? value.error : {};
20735
- const string = (v) => typeof v === "string" && v.trim() ? v : undefined;
20736
- 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}`;
20737
- const detail = string(value.detail) ?? string(nested.message) ?? string(value.message) ?? string(body);
20738
- const title = string(value.title) ?? fallback;
20739
- const param = nested.param ?? value.param;
20740
- return {
20741
- status,
20742
- message: detail ?? title,
20743
- title,
20744
- detail,
20745
- code: string(value.code) ?? string(nested.code) ?? string(nested.type) ?? string(value.error_code),
20746
- type: string(nested.type) ?? string(value.type),
20747
- param: typeof param === "string" ? param : param === null || nested.param === null ? null : undefined,
20748
- errors: Array.isArray(value.errors) ? value.errors : [],
20749
- requestId: headers.get("x-request-id") ?? string(value.requestId) ?? string(value.request_id),
20750
- raw: body
20751
- };
20752
- }
20753
-
20754
- class PraxisError extends Error {
20755
- status;
20756
- code;
20757
- type;
20758
- title;
20759
- detail;
20760
- errors;
20761
- requestId;
20762
- param;
20763
- raw;
20764
- constructor(problem = {}, options) {
20765
- super(problem.message ?? problem.detail ?? problem.title ?? `Praxis request failed${problem.status ? ` (${problem.status})` : ""}`, options);
20766
- this.name = "PraxisError";
20767
- this.status = problem.status;
20768
- this.code = problem.code;
20769
- this.type = problem.type;
20770
- this.title = problem.title;
20771
- this.detail = problem.detail;
20772
- this.errors = problem.errors ?? [];
20773
- this.requestId = problem.requestId;
20774
- this.param = problem.param;
20775
- this.raw = problem.raw;
20776
- }
20777
- static fromResponse(response, body) {
20778
- return new PraxisError(problemFrom(response.status, response.headers, body, response.statusText));
20779
- }
20780
- }
20781
-
20782
- class PraxisConnectionError extends PraxisError {
20783
- constructor(cause) {
20784
- super({ code: "CONNECTION_ERROR", title: "Unable to connect to Praxis" }, { cause });
20785
- this.name = "PraxisConnectionError";
20786
- }
20787
- }
20788
-
20789
- class PraxisTimeoutError extends PraxisError {
20790
- constructor(timeoutMs) {
20791
- super({ code: "TIMEOUT", title: `Praxis request exceeded ${timeoutMs} ms` });
20792
- this.name = "PraxisTimeoutError";
20793
- }
20794
- }
20795
-
20796
- // ../../packages/sdk/typescript/src/core/retry.ts
20797
- function canRetry(request) {
20798
- return request.method !== "POST" || Boolean(request.headers.get("Idempotency-Key")?.trim());
20799
- }
20800
- function retryAfterMs(value, now = Date.now()) {
20801
- if (!value)
20802
- return;
20803
- if (/^\d+(?:\.\d+)?$/.test(value.trim()))
20804
- return Number(value) * 1000;
20805
- const date = Date.parse(value);
20806
- return Number.isFinite(date) ? Math.max(0, date - now) : undefined;
20807
- }
20808
- function retryDelay(attempt, retryAfter, random = Math.random) {
20809
- return retryAfterMs(retryAfter) ?? Math.min(30000, 500 * 2 ** attempt) * (0.5 + random() * 0.5);
20810
- }
20811
- function abortable(promise, signal) {
20812
- signal.throwIfAborted();
20813
- return new Promise((resolve, reject) => {
20814
- const abort = () => reject(signal.reason);
20815
- signal.addEventListener("abort", abort, { once: true });
20816
- promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
20817
- });
20818
- }
20819
- function sleep(ms, signal) {
20820
- signal.throwIfAborted();
20821
- return new Promise((resolve, reject) => {
20822
- const abort = () => {
20823
- clearTimeout(timer);
20824
- reject(signal.reason);
20825
- };
20826
- const timer = setTimeout(() => {
20827
- signal.removeEventListener("abort", abort);
20828
- resolve();
20829
- }, ms);
20830
- signal.addEventListener("abort", abort, { once: true });
20831
- });
20832
- }
20833
- async function fetchWithRetry(request, fetcher, options) {
20834
- const eligible = canRetry(request);
20835
- const wait = options.wait ?? sleep;
20836
- for (let attempt = 0;; attempt++) {
20837
- options.signal.throwIfAborted();
20838
- let response;
20839
- try {
20840
- response = await abortable(fetcher(request.clone()), options.signal);
20841
- } catch (cause) {
20842
- options.signal.throwIfAborted();
20843
- if (!eligible || attempt >= options.maxRetries)
20844
- throw new PraxisConnectionError(cause);
20845
- await wait(retryDelay(attempt, null, options.random), options.signal);
20846
- continue;
20847
- }
20848
- const retriable = response.status === 408 || response.status === 429 || response.status >= 500 && response.status <= 599;
20849
- if (!eligible || !retriable || attempt >= options.maxRetries)
20850
- return response;
20851
- const delay = retryDelay(attempt, response.headers.get("Retry-After"), options.random);
20852
- await response.body?.cancel();
20853
- await wait(delay, options.signal);
20854
- }
20855
- }
20856
-
20857
21857
  // ../../packages/sdk/typescript/src/core/sse.ts
20858
21858
  async function* parseSSE(body, options = {}) {
20859
21859
  const reader = body.getReader();
@@ -21067,9 +22067,13 @@ class Transport {
21067
22067
  };
21068
22068
  }
21069
22069
  async request(operation, options = {}) {
22070
+ return (await this.requestWithResponse(operation, options)).data;
22071
+ }
22072
+ async requestWithResponse(operation, options = {}) {
21070
22073
  const scope = this.scope(options, false);
21071
22074
  try {
21072
- return (await abortable(operation(scope.options), scope.signal)).data;
22075
+ const result = await abortable(operation(scope.options), scope.signal);
22076
+ return { data: result.data, response: result.response };
21073
22077
  } finally {
21074
22078
  scope.close();
21075
22079
  }
@@ -21101,6 +22105,10 @@ function base64(bytes) {
21101
22105
  return btoa(chunks.join(""));
21102
22106
  }
21103
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
+ }
21104
22112
  const timeout = input.timeout_ms ?? 120000;
21105
22113
  if (!Number.isFinite(timeout) || timeout < 0)
21106
22114
  throw new RangeError("timeout_ms must be non-negative and finite");
@@ -21119,7 +22127,7 @@ async function publish(client2, input) {
21119
22127
  const files = Object.entries(input.files);
21120
22128
  if (files.length > 1e5)
21121
22129
  throw new PraxisError({ code: "LIMIT_EXCEEDED", message: "At most 100000 asset paths can be published" });
21122
- const manifest = {};
22130
+ let manifest = {};
21123
22131
  const contents = new Map;
21124
22132
  for (const [path2, content] of files) {
21125
22133
  const normalized = path2.startsWith("/") ? path2 : `/${path2}`;
@@ -21128,8 +22136,8 @@ async function publish(client2, input) {
21128
22136
  const bytes = typeof content === "string" ? new TextEncoder().encode(content) : new Uint8Array(content);
21129
22137
  if (bytes.length > FILE_BYTES)
21130
22138
  throw new PraxisError({ code: "LIMIT_EXCEEDED", message: `Asset ${normalized} exceeds 25 MiB` });
21131
- const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
21132
- const hash = Array.from(digest.subarray(0, 16), (byte) => byte.toString(16).padStart(2, "0")).join("");
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("");
21133
22141
  manifest[normalized] = { hash, size: bytes.length };
21134
22142
  contents.set(hash, bytes);
21135
22143
  }
@@ -21142,9 +22150,60 @@ async function publish(client2, input) {
21142
22150
  }
21143
22151
  }
21144
22152
  const created = !worker;
22153
+ if (!worker && input.dryRun)
22154
+ throw new PraxisError({ code: "NOT_FOUND", message: "请先创建应用 (create the application before dryRun)" });
21145
22155
  worker ??= await workers.create({ body: { name: input.name, subdomain: { enabled: true } } });
21146
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;
21147
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
+ }
21148
22207
  let jwt = session.buckets.length ? null : session.jwt;
21149
22208
  const uploaded = new Set;
21150
22209
  for (const bucket of session.buckets) {
@@ -21215,16 +22274,31 @@ async function publish(client2, input) {
21215
22274
  status: deployment.praxis.status,
21216
22275
  created,
21217
22276
  uploaded: uploaded.size,
21218
- reused: contents.size - uploaded.size
22277
+ reused: hashes.size - uploaded.size
21219
22278
  };
21220
22279
  }
21221
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
+
21222
22292
  // ../../packages/sdk/typescript/src/core/client.ts
21223
22293
  class Praxis {
21224
22294
  constructor(options) {
21225
22295
  const transport = new Transport(options);
21226
22296
  for (const [name, create] of Object.entries(resourceFactories)) {
21227
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) });
21228
22302
  if (name === "application")
21229
22303
  Object.assign(resource, { publish: (input) => publish(this, input) });
21230
22304
  Object.defineProperty(this, name, { value: resource, enumerable: true });
@@ -22356,7 +23430,7 @@ function plain(value) {
22356
23430
  }
22357
23431
 
22358
23432
  // src/output/human.ts
22359
- var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
23433
+ var count3 = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
22360
23434
  function identity(result, ctx) {
22361
23435
  const op = "op" in result ? result.op : undefined;
22362
23436
  const split = op?.lastIndexOf(".") ?? -1;
@@ -22444,7 +23518,7 @@ function objectView(data, resource, id, ctx, paint) {
22444
23518
  return v.map(scalar).map(plain).join(", ");
22445
23519
  folded = true;
22446
23520
  const preview = v.slice(0, 3).map((item) => record(item).id ?? record(item).name).filter((x) => x !== undefined).map((x) => plain(scalar(x)));
22447
- return `${count(v.length, "item")}${preview.length ? ` (${preview.join(", ")})` : ""}`;
23521
+ return `${count3(v.length, "item")}${preview.length ? ` (${preview.join(", ")})` : ""}`;
22448
23522
  }
22449
23523
  if (v !== null && typeof v === "object") {
22450
23524
  if (depth >= 1) {
@@ -22485,7 +23559,7 @@ function renderHuman(result, ctx) {
22485
23559
  return {
22486
23560
  stdout: result.items.length ? table(result.items, ctx, out) : out.dim(`No ${plain(resource)}${/(s|x|ch|sh)$/.test(resource) ? "es" : "s"}.`) + `
22487
23561
  `,
22488
- stderr: err.dim(`${result.total !== undefined ? `${result.items.length} of ${result.total} items` : count(result.items.length, "item")}${result.nextCursor ? ` · next: ${ctx.nextCommand ?? "praxis --help"}` : ""}`) + `
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"}` : ""}`) + `
22489
23563
  `
22490
23564
  };
22491
23565
  case "object": {
@@ -22765,7 +23839,7 @@ function startProgress(ctx, write = (text) => writeOutput({ stderr: text })) {
22765
23839
  }
22766
23840
 
22767
23841
  // src/main.ts
22768
- var version = "0.1.0-dev.9d9e2b6";
23842
+ var version = "0.1.0-dev.a3beed2";
22769
23843
  var commands = commandTree(operations);
22770
23844
  var manual = [["login"], ["logout"], ["whoami"], ["org", "list"], ["org", "switch"], ["api"], ["skill"]];
22771
23845
  function route(argv) {