PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
← All changes | includes/agents/rest.php +199 -126 0.9.81.1.10 View file →
@@ -1,7 +1,7 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Agents: REST surface at /desktop-mode/v1/agents.
3 + * OpenStation — Agents: REST surface at /desktop-mode/v1/agents.
4 4 *
5 5 * One CRUD surface over the two layers (user row + definition meta) so
6 6 * the bundle never coordinates `/wp/v2/users` and raw meta from JS.
7 7 *
@@ -18,13 +18,13 @@
18 18 * GET /desktop-mode/v1/agents/hooks-catalogue hook autocomplete
19 19 * GET /desktop-mode/v1/agents/roles assignable roles (writers only)
20 20 *
21 21 * Permissions: reads and invokes default to `edit_posts` (the same
22 - * audience as the site folder window hosting the UI); writes require
22 + * audience as the WP Explorer window hosting the UI); writes require
23 23 * `edit_users` (agents are real users — managing them is user
24 24 * management). All three are filterable.
25 25 *
26 - * @package WPDesktopMode
26 + * @package OpenStation
27 27 */
28 28
29 29 defined( 'ABSPATH' ) || exit;
30 30
@@ -32,9 +32,9 @@
32 32 * Register REST routes on rest_api_init.
33 33 *
34 34 * @return void
35 35 */
36 -function desktop_mode_agents_register_rest_routes() {
36 +function openstation_agents_register_rest_routes() {
37 37 $namespace = 'desktop-mode/v1';
38 38
39 39 register_rest_route(
40 40 $namespace,
@@ -41,15 +41,15 @@
41 41 '/agents',
42 42 array(
43 43 array(
44 44 'methods' => WP_REST_Server::READABLE,
45 - 'permission_callback' => 'desktop_mode_agents_rest_read_permission',
46 - 'callback' => 'desktop_mode_agents_rest_list',
45 + 'permission_callback' => 'openstation_agents_rest_read_permission',
46 + 'callback' => 'openstation_agents_rest_list',
47 47 ),
48 48 array(
49 49 'methods' => WP_REST_Server::CREATABLE,
50 - 'permission_callback' => 'desktop_mode_agents_rest_write_permission',
51 - 'callback' => 'desktop_mode_agents_rest_create',
50 + 'permission_callback' => 'openstation_agents_rest_write_permission',
51 + 'callback' => 'openstation_agents_rest_create',
52 52 'args' => array(
53 53 'name' => array(
54 54 'type' => 'string',
55 55 'required' => true,
@@ -73,8 +73,35 @@
73 73 'type' => 'array',
74 74 'default' => array(),
75 75 'items' => array( 'type' => 'string' ),
76 76 ),
77 + // Like `face`, deliberately schema-light. Each row
78 + // is validated against the live trigger-kind
79 + // catalogue by openstation_agent_sanitize_triggers(),
80 + // which drops rows it does not recognise rather
81 + // than rejecting the whole create.
82 + 'triggers' => array(
83 + 'type' => 'array',
84 + 'default' => array(),
85 + ),
86 + 'vibes' => array(
87 + 'type' => 'string',
88 + 'default' => '',
89 + ),
90 + // `face` carries no schema beyond "object" and no
91 + // sanitize_callback on purpose. The real validator is
92 + // openstation_agent_sanitize_face_json(), which clamps
93 + // every number; a partial JSON Schema here would only
94 + // suggest the route had checked it.
95 + 'face' => array(
96 + 'type' => 'object',
97 + 'default' => null,
98 + ),
99 + 'faceSeed' => array(
100 + 'type' => 'integer',
101 + 'default' => 0,
102 + 'sanitize_callback' => 'absint',
103 + ),
77 104 ),
78 105 ),
79 106 )
80 107 );
@@ -83,20 +110,38 @@
83 110 $namespace,
84 111 '/agents/abilities',
85 112 array(
86 113 'methods' => WP_REST_Server::READABLE,
87 - 'permission_callback' => 'desktop_mode_agents_rest_read_permission',
88 - 'callback' => 'desktop_mode_agents_rest_abilities_catalogue',
114 + 'permission_callback' => 'openstation_agents_rest_read_permission',
115 + 'callback' => 'openstation_agents_rest_abilities_catalogue',
89 116 )
90 117 );
91 118
92 119 register_rest_route(
93 120 $namespace,
121 + '/agents/draft',
122 + array(
123 + 'methods' => WP_REST_Server::CREATABLE,
124 + 'permission_callback' => 'openstation_agents_rest_write_permission',
125 + 'callback' => 'openstation_agents_rest_draft',
126 + 'args' => array(
127 + 'brief' => array(
128 + 'type' => 'string',
129 + 'required' => true,
130 + 'sanitize_callback' => 'sanitize_textarea_field',
131 + 'validate_callback' => 'openstation_agents_rest_validate_brief',
132 + ),
133 + ),
134 + )
135 + );
136 +
137 + register_rest_route(
138 + $namespace,
94 139 '/agents/trigger-kinds',
95 140 array(
96 141 'methods' => WP_REST_Server::READABLE,
97 - 'permission_callback' => 'desktop_mode_agents_rest_read_permission',
98 - 'callback' => 'desktop_mode_agents_rest_trigger_kinds',
142 + 'permission_callback' => 'openstation_agents_rest_read_permission',
143 + 'callback' => 'openstation_agents_rest_trigger_kinds',
99 144 )
100 145 );
101 146
102 147 register_rest_route(
@@ -103,10 +148,10 @@
103 148 $namespace,
104 149 '/agents/hooks-catalogue',
105 150 array(
106 151 'methods' => WP_REST_Server::READABLE,
107 - 'permission_callback' => 'desktop_mode_agents_rest_read_permission',
108 - 'callback' => 'desktop_mode_agents_rest_hooks_catalogue',
152 + 'permission_callback' => 'openstation_agents_rest_read_permission',
153 + 'callback' => 'openstation_agents_rest_hooks_catalogue',
109 154 )
110 155 );
111 156
112 157 register_rest_route(
@@ -113,10 +158,10 @@
113 158 $namespace,
114 159 '/agents/roles',
115 160 array(
116 161 'methods' => WP_REST_Server::READABLE,
117 - 'permission_callback' => 'desktop_mode_agents_rest_write_permission',
118 - 'callback' => 'desktop_mode_agents_rest_roles',
162 + 'permission_callback' => 'openstation_agents_rest_write_permission',
163 + 'callback' => 'openstation_agents_rest_roles',
119 164 )
120 165 );
121 166
122 167 register_rest_route(
@@ -124,20 +169,20 @@
124 169 '/agents/(?P<id>\d+)',
125 170 array(
126 171 array(
127 172 'methods' => WP_REST_Server::READABLE,
128 - 'permission_callback' => 'desktop_mode_agents_rest_read_permission',
129 - 'callback' => 'desktop_mode_agents_rest_get',
173 + 'permission_callback' => 'openstation_agents_rest_read_permission',
174 + 'callback' => 'openstation_agents_rest_get',
130 175 ),
131 176 array(
132 177 'methods' => WP_REST_Server::CREATABLE,
133 - 'permission_callback' => 'desktop_mode_agents_rest_write_permission',
134 - 'callback' => 'desktop_mode_agents_rest_patch',
178 + 'permission_callback' => 'openstation_agents_rest_write_permission',
179 + 'callback' => 'openstation_agents_rest_patch',
135 180 ),
136 181 array(
137 182 'methods' => WP_REST_Server::DELETABLE,
138 - 'permission_callback' => 'desktop_mode_agents_rest_write_permission',
139 - 'callback' => 'desktop_mode_agents_rest_delete',
183 + 'permission_callback' => 'openstation_agents_rest_write_permission',
184 + 'callback' => 'openstation_agents_rest_delete',
140 185 ),
141 186 )
142 187 );
143 188
@@ -145,17 +190,25 @@
145 190 $namespace,
146 191 '/agents/(?P<id>\d+)/invoke',
147 192 array(
148 193 'methods' => WP_REST_Server::CREATABLE,
149 - 'permission_callback' => 'desktop_mode_agents_rest_invoke_permission',
150 - 'callback' => 'desktop_mode_agents_rest_invoke',
194 + 'permission_callback' => 'openstation_agents_rest_invoke_permission',
195 + 'callback' => 'openstation_agents_rest_invoke',
151 196 'args' => array(
152 - 'message' => array(
197 + 'async' => array(
198 + 'type' => 'boolean',
199 + 'default' => false,
200 + ),
201 + 'requestId' => array(
202 + 'type' => 'string',
203 + 'format' => 'uuid',
204 + ),
205 + 'message' => array(
153 206 'type' => 'string',
154 207 'required' => true,
155 208 'sanitize_callback' => 'sanitize_textarea_field',
156 209 ),
157 - 'source' => array(
210 + 'source' => array(
158 211 'type' => 'string',
159 212 'default' => 'chat',
160 213 'enum' => array( 'chat', 'drag', 'send-to' ),
161 214 'sanitize_callback' => 'sanitize_key',
@@ -163,9 +216,9 @@
163 216 // Prior conversation turns, oldest first. Without these
164 217 // every message is a contextless run — a follow-up like
165 218 // "yes, do it" would be resolved against nothing and the
166 219 // agent could act on the wrong entity entirely.
167 - 'history' => array(
220 + 'history' => array(
168 221 'type' => 'array',
169 222 'default' => array(),
170 223 'items' => array(
171 224 'type' => 'object',
@@ -181,66 +234,29 @@
181 234 ),
182 235 )
183 236 );
184 237 }
185 -add_action( 'rest_api_init', 'desktop_mode_agents_register_rest_routes' );
238 +add_action( 'rest_api_init', 'openstation_agents_register_rest_routes' );
186 239
187 240 // ---------------------------------------------------------------------------
188 241 // Permissions
242 +//
243 +// The three capability gates themselves (`openstation_agents_user_can_read`
244 +// / `_manage` / `_invoke`) live in bootstrap.php: the WP Explorer
245 +// integration loads while the feature flag is off, and this file does
246 +// not.
189 247 // ---------------------------------------------------------------------------
190 248
191 249 /**
192 - * Whether the current user can see agents.
193 - *
194 - * @return bool
195 - */
196 -function desktop_mode_agents_user_can_read() {
197 - /**
198 - * Filter whether the current user can read Desktop Mode agents.
199 - *
200 - * @param bool $can Default: `edit_posts` capability.
201 - */
202 - return (bool) apply_filters( 'desktop_mode_agents_user_can_read', current_user_can( 'edit_posts' ) );
203 -}
204 -
205 -/**
206 - * Whether the current user can create / edit / delete agents.
207 - *
208 - * @return bool
209 - */
210 -function desktop_mode_agents_user_can_manage() {
211 - /**
212 - * Filter whether the current user can manage Desktop Mode agents.
213 - *
214 - * @param bool $can Default: `edit_users` capability.
215 - */
216 - return (bool) apply_filters( 'desktop_mode_agents_user_can_manage', current_user_can( 'edit_users' ) );
217 -}
218 -
219 -/**
220 - * Whether the current user can invoke agents.
221 - *
222 - * @return bool
223 - */
224 -function desktop_mode_agents_user_can_invoke() {
225 - /**
226 - * Filter whether the current user can invoke Desktop Mode agents.
227 - *
228 - * @param bool $can Default: `edit_posts` capability.
229 - */
230 - return (bool) apply_filters( 'desktop_mode_agents_user_can_invoke', current_user_can( 'edit_posts' ) );
231 -}
232 -
233 -/**
234 250 * Read-route permission callback.
235 251 *
236 252 * @return bool|WP_Error
237 253 */
238 -function desktop_mode_agents_rest_read_permission() {
239 - if ( ! is_user_logged_in() || ! desktop_mode_agents_user_can_read() ) {
254 +function openstation_agents_rest_read_permission() {
255 + if ( ! is_user_logged_in() || ! openstation_agents_user_can_read() ) {
240 256 return new WP_Error(
241 - 'desktop_mode_agents_forbidden',
242 - __( 'You do not have permission to read Desktop Mode agents.', 'desktop-mode' ),
257 + 'openstation_agents_forbidden',
258 + __( 'You do not have permission to read OpenStation agents.', 'desktop-mode' ),
243 259 array( 'status' => rest_authorization_required_code() )
244 260 );
245 261 }
246 262 return true;
@@ -250,13 +266,13 @@
250 266 * Write-route permission callback.
251 267 *
252 268 * @return bool|WP_Error
253 269 */
254 -function desktop_mode_agents_rest_write_permission() {
255 - if ( ! is_user_logged_in() || ! desktop_mode_agents_user_can_manage() ) {
270 +function openstation_agents_rest_write_permission() {
271 + if ( ! is_user_logged_in() || ! openstation_agents_user_can_manage() ) {
256 272 return new WP_Error(
257 - 'desktop_mode_agents_forbidden',
258 - __( 'You do not have permission to manage Desktop Mode agents.', 'desktop-mode' ),
273 + 'openstation_agents_forbidden',
274 + __( 'You do not have permission to manage OpenStation agents.', 'desktop-mode' ),
259 275 array( 'status' => rest_authorization_required_code() )
260 276 );
261 277 }
262 278 return true;
@@ -266,13 +282,13 @@
266 282 * Invoke-route permission callback.
267 283 *
268 284 * @return bool|WP_Error
269 285 */
270 -function desktop_mode_agents_rest_invoke_permission() {
271 - if ( ! is_user_logged_in() || ! desktop_mode_agents_user_can_invoke() ) {
286 +function openstation_agents_rest_invoke_permission() {
287 + if ( ! is_user_logged_in() || ! openstation_agents_user_can_invoke() ) {
272 288 return new WP_Error(
273 - 'desktop_mode_agents_forbidden',
274 - __( 'You do not have permission to invoke Desktop Mode agents.', 'desktop-mode' ),
289 + 'openstation_agents_forbidden',
290 + __( 'You do not have permission to invoke OpenStation agents.', 'desktop-mode' ),
275 291 array( 'status' => rest_authorization_required_code() )
276 292 );
277 293 }
278 294 return true;
@@ -286,18 +302,18 @@
286 302 * GET /agents — list every agent on the site.
287 303 *
288 304 * @return WP_REST_Response
289 305 */
290 -function desktop_mode_agents_rest_list() {
306 +function openstation_agents_rest_list() {
291 307 $out = array();
292 - foreach ( desktop_mode_agent_get_agents() as $user ) {
293 - $shape = desktop_mode_agents_rest_shape_user( $user );
308 + foreach ( openstation_agent_get_agents() as $user ) {
309 + $shape = openstation_agents_rest_shape_user( $user );
294 310 if ( $shape ) {
295 311 $out[] = $shape;
296 312 }
297 313 }
298 314 $response = rest_ensure_response( $out );
299 - // Standard collection headers — the site folder's root grid derives
315 + // Standard collection headers — WP Explorer's root grid derives
300 316 // its folder counts from `X-WP-Total`.
301 317 $response->header( 'X-WP-Total', (string) count( $out ) );
302 318 $response->header( 'X-WP-TotalPages', '1' );
303 319 return $response;
@@ -308,18 +324,18 @@
308 324 *
309 325 * @param WP_REST_Request $request REST request.
310 326 * @return WP_REST_Response|WP_Error
311 327 */
312 -function desktop_mode_agents_rest_get( WP_REST_Request $request ) {
328 +function openstation_agents_rest_get( WP_REST_Request $request ) {
313 329 $user = get_userdata( (int) $request['id'] );
314 - if ( ! $user || ! desktop_mode_agent_is_agent( $user ) ) {
330 + if ( ! $user || ! openstation_agent_is_agent( $user ) ) {
315 331 return new WP_Error(
316 - 'desktop_mode_agents_not_found',
332 + 'openstation_agents_not_found',
317 333 __( 'Agent not found.', 'desktop-mode' ),
318 334 array( 'status' => 404 )
319 335 );
320 336 }
321 - return rest_ensure_response( desktop_mode_agents_rest_shape_user( $user ) );
337 + return rest_ensure_response( openstation_agents_rest_shape_user( $user ) );
322 338 }
323 339
324 340 /**
325 341 * POST /agents — create.
@@ -326,10 +342,15 @@
326 342 *
327 343 * @param WP_REST_Request $request REST request.
328 344 * @return WP_REST_Response|WP_Error
329 345 */
330 -function desktop_mode_agents_rest_create( WP_REST_Request $request ) {
331 - $user = desktop_mode_agent_create(
346 +function openstation_agents_rest_create( WP_REST_Request $request ) {
347 + // Every field the route declares is forwarded. `vibes`, `face` and
348 + // `faceSeed` are the character half of an agent, and a create that
349 + // took the name and dropped the portrait is how an agent ends up
350 + // wearing the fallback glyph seconds after someone picked a face
351 + // for it. `openstation_agent_create()` sanitizes each one.
352 + $user = openstation_agent_create(
332 353 array(
333 354 'name' => (string) $request['name'],
334 355 'role' => (string) $request['role'],
335 356 'description' => (string) $request['description'],
@@ -334,8 +355,12 @@
334 355 'role' => (string) $request['role'],
335 356 'description' => (string) $request['description'],
336 357 'instructions' => (string) $request['instructions'],
337 358 'abilities' => (array) $request['abilities'],
359 + 'triggers' => (array) $request['triggers'],
360 + 'vibes' => (string) $request['vibes'],
361 + 'face' => $request['face'],
362 + 'faceSeed' => (int) $request['faceSeed'],
338 363 )
339 364 );
340 365 if ( is_wp_error( $user ) ) {
341 366 $data = $user->get_error_data();
@@ -344,9 +369,9 @@
344 369 }
345 370 return $user;
346 371 }
347 372
348 - $response = rest_ensure_response( desktop_mode_agents_rest_shape_user( $user ) );
373 + $response = rest_ensure_response( openstation_agents_rest_shape_user( $user ) );
349 374 $response->set_status( 201 );
350 375 return $response;
351 376 }
352 377
@@ -355,13 +380,13 @@
355 380 *
356 381 * @param WP_REST_Request $request REST request.
357 382 * @return WP_REST_Response|WP_Error
358 383 */
359 -function desktop_mode_agents_rest_patch( WP_REST_Request $request ) {
384 +function openstation_agents_rest_patch( WP_REST_Request $request ) {
360 385 $user = get_userdata( (int) $request['id'] );
361 - if ( ! $user || ! desktop_mode_agent_is_agent( $user ) ) {
386 + if ( ! $user || ! openstation_agent_is_agent( $user ) ) {
362 387 return new WP_Error(
363 - 'desktop_mode_agents_not_found',
388 + 'openstation_agents_not_found',
364 389 __( 'Agent not found.', 'desktop-mode' ),
365 390 array( 'status' => 404 )
366 391 );
367 392 }
@@ -374,9 +399,21 @@
374 399 $body = array();
375 400 }
376 401
377 402 $fields = array();
378 - $allowed = array( 'name', 'role', 'description', 'instructions', 'abilities', 'triggers', 'model', 'rateLimit' );
403 + $allowed = array(
404 + 'name',
405 + 'role',
406 + 'description',
407 + 'instructions',
408 + 'abilities',
409 + 'triggers',
410 + 'model',
411 + 'rateLimit',
412 + 'vibes',
413 + 'face',
414 + 'faceSeed',
415 + );
379 416 foreach ( $allowed as $field ) {
380 417 if ( array_key_exists( $field, $body ) ) {
381 418 $fields[ $field ] = $body[ $field ];
382 419 }
@@ -381,9 +418,9 @@
381 418 $fields[ $field ] = $body[ $field ];
382 419 }
383 420 }
384 421
385 - $updated = desktop_mode_agent_update( (int) $user->ID, $fields );
422 + $updated = openstation_agent_update( (int) $user->ID, $fields );
386 423 if ( is_wp_error( $updated ) ) {
387 424 $updated->add_data( array( 'status' => 400 ) );
388 425 return $updated;
389 426 }
@@ -388,9 +425,9 @@
388 425 return $updated;
389 426 }
390 427
391 428 return rest_ensure_response(
392 - desktop_mode_agents_rest_shape_user( get_userdata( (int) $user->ID ) )
429 + openstation_agents_rest_shape_user( get_userdata( (int) $user->ID ) )
393 430 );
394 431 }
395 432
396 433 /**
@@ -398,20 +435,20 @@
398 435 *
399 436 * @param WP_REST_Request $request REST request.
400 437 * @return WP_REST_Response|WP_Error
401 438 */
402 -function desktop_mode_agents_rest_delete( WP_REST_Request $request ) {
439 +function openstation_agents_rest_delete( WP_REST_Request $request ) {
403 440 $user_id = (int) $request['id'];
404 441 $user = get_userdata( $user_id );
405 - if ( ! $user || ! desktop_mode_agent_is_agent( $user ) ) {
442 + if ( ! $user || ! openstation_agent_is_agent( $user ) ) {
406 443 return new WP_Error(
407 - 'desktop_mode_agents_not_found',
444 + 'openstation_agents_not_found',
408 445 __( 'Agent not found.', 'desktop-mode' ),
409 446 array( 'status' => 404 )
410 447 );
411 448 }
412 449
413 - $result = desktop_mode_agent_delete( $user_id );
450 + $result = openstation_agent_delete( $user_id );
414 451 if ( is_wp_error( $result ) ) {
415 452 $result->add_data( array( 'status' => 500 ) );
416 453 return $result;
417 454 }
@@ -429,13 +466,13 @@
429 466 *
430 467 * @param WP_REST_Request $request REST request.
431 468 * @return WP_REST_Response|WP_Error
432 469 */
433 -function desktop_mode_agents_rest_invoke( WP_REST_Request $request ) {
470 +function openstation_agents_rest_invoke( WP_REST_Request $request ) {
434 471 $user = get_userdata( (int) $request['id'] );
435 - if ( ! $user || ! desktop_mode_agent_is_agent( $user ) ) {
472 + if ( ! $user || ! openstation_agent_is_agent( $user ) ) {
436 473 return new WP_Error(
437 - 'desktop_mode_agents_not_found',
474 + 'openstation_agents_not_found',
438 475 __( 'Agent not found.', 'desktop-mode' ),
439 476 array( 'status' => 404 )
440 477 );
441 478 }
@@ -444,17 +481,21 @@
444 481
445 482 // Per-agent gate. The route's `permission_callback` cannot run this
446 483 // one: it has no access to the resolved agent, and the capability an
447 484 // agent requires is a property of that agent's trigger config.
448 - if ( ! desktop_mode_agent_user_can_invoke_agent( (int) $user->ID, $source ) ) {
485 + if ( ! openstation_agent_user_can_invoke_agent( (int) $user->ID, $source ) ) {
449 486 return new WP_Error(
450 - 'desktop_mode_agents_forbidden',
487 + 'openstation_agents_forbidden',
451 488 __( 'You do not have permission to invoke this agent.', 'desktop-mode' ),
452 489 array( 'status' => rest_authorization_required_code() )
453 490 );
454 491 }
455 492
456 - $result = desktop_mode_agent_invoke(
493 + if ( $request['async'] ) {
494 + return openstation_agents_rest_enqueue_job( $request );
495 + }
496 +
497 + $result = openstation_agent_invoke(
457 498 (int) $user->ID,
458 499 (string) $request['message'],
459 500 array(
460 501 'source' => $source,
@@ -476,19 +517,48 @@
476 517 * GET /agents/abilities — the abilities catalogue for the picker.
477 518 *
478 519 * @return WP_REST_Response
479 520 */
480 -function desktop_mode_agents_rest_abilities_catalogue() {
481 - return rest_ensure_response( desktop_mode_agents_abilities_catalogue() );
521 +function openstation_agents_rest_abilities_catalogue() {
522 + return rest_ensure_response( openstation_agents_abilities_catalogue() );
482 523 }
483 524
484 525 /**
526 + * `brief` must carry words and fit the drafting cap.
527 + *
528 + * @param mixed $value Raw param.
529 + * @return bool
530 + */
531 +function openstation_agents_rest_validate_brief( $value ) {
532 + return is_string( $value )
533 + && '' !== trim( $value )
534 + && mb_strlen( $value ) <= OPENSTATION_AGENT_DRAFT_BRIEF_MAX;
535 +}
536 +
537 +/**
538 + * POST /agents/draft — draft a definition from a brief.
539 + *
540 + * Nothing is created: the wizard shows the draft for review and the
541 + * create route is still the only way an agent comes to exist.
542 + *
543 + * @param WP_REST_Request $request Request.
544 + * @return WP_REST_Response|WP_Error
545 + */
546 +function openstation_agents_rest_draft( WP_REST_Request $request ) {
547 + $draft = openstation_agent_draft( (string) $request['brief'], get_current_user_id() );
548 + if ( is_wp_error( $draft ) ) {
549 + return $draft;
550 + }
551 + return rest_ensure_response( $draft );
552 +}
553 +
554 +/**
485 555 * GET /agents/trigger-kinds — the trigger-kinds catalogue.
486 556 *
487 557 * @return WP_REST_Response
488 558 */
489 -function desktop_mode_agents_rest_trigger_kinds() {
490 - return rest_ensure_response( desktop_mode_agent_trigger_kinds() );
559 +function openstation_agents_rest_trigger_kinds() {
560 + return rest_ensure_response( openstation_agent_trigger_kinds() );
491 561 }
492 562
493 563 /**
494 564 * GET /agents/hooks-catalogue — the curated WP hooks catalogue.
@@ -494,10 +564,10 @@
494 564 * GET /agents/hooks-catalogue — the curated WP hooks catalogue.
495 565 *
496 566 * @return WP_REST_Response
497 567 */
498 -function desktop_mode_agents_rest_hooks_catalogue() {
499 - return rest_ensure_response( desktop_mode_agent_hooks_catalogue() );
568 +function openstation_agents_rest_hooks_catalogue() {
569 + return rest_ensure_response( openstation_agent_hooks_catalogue() );
500 570 }
501 571
502 572 /**
503 573 * GET /agents/roles — roles the current user may assign to an agent.
@@ -503,12 +573,12 @@
503 573 * GET /agents/roles — roles the current user may assign to an agent.
504 574 *
505 575 * @return WP_REST_Response
506 576 */
507 -function desktop_mode_agents_rest_roles() {
577 +function openstation_agents_rest_roles() {
508 578 $names = wp_roles()->get_names();
509 579 $out = array();
510 - foreach ( desktop_mode_agent_allowed_roles() as $slug ) {
580 + foreach ( openstation_agent_allowed_roles() as $slug ) {
511 581 $out[] = array(
512 582 'slug' => $slug,
513 583 'label' => isset( $names[ $slug ] ) ? translate_user_role( $names[ $slug ] ) : $slug,
514 584 );
@@ -521,10 +591,10 @@
521 591 *
522 592 * @param WP_User|null $user Agent user.
523 593 * @return array|null Null when the user is not an agent.
524 594 */
525 -function desktop_mode_agents_rest_shape_user( $user ) {
526 - if ( ! $user instanceof WP_User || ! desktop_mode_agent_is_agent( $user ) ) {
595 +function openstation_agents_rest_shape_user( $user ) {
596 + if ( ! $user instanceof WP_User || ! openstation_agent_is_agent( $user ) ) {
527 597 return null;
528 598 }
529 599
530 600 $slug = (string) $user->user_login;
@@ -538,9 +608,9 @@
538 608 }
539 609
540 610 $avatar = get_avatar_url( $user->ID, array( 'size' => 96 ) );
541 611 if ( ! is_string( $avatar ) || '' === $avatar ) {
542 - $avatar = desktop_mode_agent_avatar_url();
612 + $avatar = openstation_agent_avatar_url( (int) $user->ID );
543 613 }
544 614
545 615 return array(
546 616 'id' => (int) $user->ID,
@@ -545,14 +615,17 @@
545 615 return array(
546 616 'id' => (int) $user->ID,
547 617 'slug' => $slug,
548 618 'name' => (string) $user->display_name,
549 - 'description' => desktop_mode_agent_get_description( (int) $user->ID ),
550 - 'instructions' => desktop_mode_agent_get_instructions( (int) $user->ID ),
619 + 'description' => openstation_agent_get_description( (int) $user->ID ),
620 + 'instructions' => openstation_agent_get_instructions( (int) $user->ID ),
551 621 'role' => $role,
552 - 'abilities' => desktop_mode_agent_get_abilities( (int) $user->ID ),
553 - 'triggers' => desktop_mode_agent_get_triggers( (int) $user->ID ),
554 - 'model' => desktop_mode_agent_get_model( (int) $user->ID ),
555 - 'rateLimit' => desktop_mode_agent_get_rate_limit( (int) $user->ID ),
622 + 'abilities' => openstation_agent_get_abilities( (int) $user->ID ),
623 + 'triggers' => openstation_agent_get_triggers( (int) $user->ID ),
624 + 'model' => openstation_agent_get_model( (int) $user->ID ),
625 + 'rateLimit' => openstation_agent_get_rate_limit( (int) $user->ID ),
626 + 'vibes' => openstation_agent_get_vibes( (int) $user->ID ),
627 + 'face' => openstation_agent_get_face( (int) $user->ID ),
628 + 'faceSeed' => openstation_agent_get_face_seed( (int) $user->ID ),
556 629 'avatarUrl' => $avatar,
557 630 );
558 631 }