oomi-ai 0.2.50 → 0.3.0

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 (88) hide show
  1. package/README.md +203 -507
  2. package/agent_instructions.md +244 -253
  3. package/bin/oomi-ai.js +4026 -5795
  4. package/bin/sessionBridgeState.js +78 -78
  5. package/lib/openclawPaths.js +70 -71
  6. package/lib/openclawProfile.js +216 -216
  7. package/lib/personaApiClient.js +133 -303
  8. package/lib/spokenMetadata.js +137 -137
  9. package/openclaw.extension.js +341 -341
  10. package/openclaw.plugin.json +17 -17
  11. package/package.json +59 -59
  12. package/persona-app/README.md +27 -0
  13. package/persona-app/registry/v1.json +63 -0
  14. package/persona-app/schema/persona-app.v1.schema.json +90 -0
  15. package/skills/oomi/SKILL.md +165 -182
  16. package/skills/oomi/agent_instructions.md +99 -80
  17. package/lib/channelPluginClient.js +0 -119
  18. package/lib/openclawDevGateway.js +0 -384
  19. package/lib/personaJobExecutor.js +0 -139
  20. package/lib/personaJobPoller.js +0 -112
  21. package/lib/personaPortAllocator.js +0 -36
  22. package/lib/personaRuntimeManager.js +0 -496
  23. package/lib/personaRuntimeProcess.js +0 -924
  24. package/lib/personaRuntimeRegistry.js +0 -67
  25. package/lib/personaRuntimeSupervisor.js +0 -330
  26. package/lib/scaffold.js +0 -108
  27. package/lib/template.js +0 -45
  28. package/skills/oomi/config.json +0 -3
  29. package/skills/oomi/scripts/get_avatar_capabilities.py +0 -40
  30. package/skills/oomi/scripts/get_data.py +0 -49
  31. package/skills/oomi/scripts/install_agent_instructions.py +0 -78
  32. package/skills/oomi/scripts/send_goal.py +0 -53
  33. package/skills/oomi/scripts/sync.py +0 -46
  34. package/skills/oomi/setup.py +0 -41
  35. package/templates/persona-app/.env.example +0 -8
  36. package/templates/persona-app/README.md +0 -58
  37. package/templates/persona-app/eslint.config.js +0 -28
  38. package/templates/persona-app/index.html +0 -18
  39. package/templates/persona-app/oomi.runtime.json +0 -13
  40. package/templates/persona-app/package.json +0 -44
  41. package/templates/persona-app/persona/brief.md +0 -14
  42. package/templates/persona-app/persona.json +0 -14
  43. package/templates/persona-app/public/manifest.webmanifest +0 -8
  44. package/templates/persona-app/public/oomi.health.json +0 -6
  45. package/templates/persona-app/src/App.css +0 -379
  46. package/templates/persona-app/src/App.tsx +0 -17
  47. package/templates/persona-app/src/index.css +0 -53
  48. package/templates/persona-app/src/main.tsx +0 -23
  49. package/templates/persona-app/src/pages/HomePage.tsx +0 -127
  50. package/templates/persona-app/src/pages/ScenePage.tsx +0 -158
  51. package/templates/persona-app/src/persona/config.ts +0 -6
  52. package/templates/persona-app/src/persona/notes.ts +0 -10
  53. package/templates/persona-app/src/spatial.ts +0 -82
  54. package/templates/persona-app/src/vite-env.d.ts +0 -3
  55. package/templates/persona-app/template.json +0 -13
  56. package/templates/persona-app/tsconfig.app.json +0 -23
  57. package/templates/persona-app/tsconfig.json +0 -7
  58. package/templates/persona-app/tsconfig.node.json +0 -21
  59. package/templates/persona-app/vendor/webspatial/FORK.md +0 -6
  60. package/templates/persona-app/vendor/webspatial/core-sdk/LICENSE +0 -21
  61. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.d.ts +0 -906
  62. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js +0 -75
  63. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js.map +0 -1
  64. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.d.ts +0 -906
  65. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js +0 -3131
  66. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js.map +0 -1
  67. package/templates/persona-app/vendor/webspatial/core-sdk/package.json +0 -45
  68. package/templates/persona-app/vendor/webspatial/react-sdk/LICENSE +0 -21
  69. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.d.ts +0 -365
  70. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js +0 -4167
  71. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js.map +0 -1
  72. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.d.ts +0 -82
  73. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js +0 -66
  74. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js.map +0 -1
  75. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.d.ts +0 -2
  76. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js +0 -18
  77. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js.map +0 -1
  78. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.d.ts +0 -5
  79. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js +0 -66
  80. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js.map +0 -1
  81. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.d.ts +0 -1
  82. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js +0 -18
  83. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js.map +0 -1
  84. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.d.ts +0 -365
  85. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js +0 -4207
  86. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js.map +0 -1
  87. package/templates/persona-app/vendor/webspatial/react-sdk/package.json +0 -94
  88. package/templates/persona-app/vite.config.ts +0 -31
@@ -1,313 +1,143 @@
1
- function trimString(value) {
2
- return typeof value === 'string' ? value.trim() : '';
3
- }
4
-
5
- function stripTrailingSlash(value) {
6
- return trimString(value).replace(/\/+$/, '');
7
- }
8
-
9
- async function readJsonResponse(response) {
10
- return response.json().catch(() => ({}));
11
- }
12
-
13
- async function getJson({ fetchImpl, backendUrl, path, deviceToken }) {
14
- const baseUrl = stripTrailingSlash(backendUrl);
15
- if (!baseUrl) {
16
- throw new Error('Backend URL is required.');
17
- }
18
-
19
- const headers = {};
20
- const token = trimString(deviceToken);
21
- if (token) {
22
- headers.Authorization = `Bearer ${token}`;
23
- }
24
-
25
- const response = await fetchImpl(`${baseUrl}${path}`, {
26
- method: 'GET',
27
- headers,
28
- });
29
-
30
- const payload = await readJsonResponse(response);
31
- if (!response.ok) {
32
- const errorMessage =
33
- trimString(payload?.error) ||
34
- trimString(payload?.message) ||
35
- `Persona API request failed (${response.status})`;
36
- const error = new Error(errorMessage);
37
- error.status = response.status;
38
- error.payload = payload;
39
- throw error;
40
- }
41
-
42
- return payload;
43
- }
44
-
45
- async function postJson({ fetchImpl, backendUrl, path, deviceToken, body }) {
46
- const baseUrl = stripTrailingSlash(backendUrl);
47
- if (!baseUrl) {
48
- throw new Error('Backend URL is required.');
49
- }
50
- const token = trimString(deviceToken);
51
- if (!token) {
52
- throw new Error('Device token is required.');
53
- }
54
-
55
- const response = await fetchImpl(`${baseUrl}${path}`, {
56
- method: 'POST',
57
- headers: {
58
- 'Content-Type': 'application/json',
59
- Authorization: `Bearer ${token}`,
60
- },
61
- body: JSON.stringify(body),
62
- });
63
-
64
- const payload = await readJsonResponse(response);
65
- if (!response.ok) {
66
- const errorMessage =
67
- trimString(payload?.error) ||
68
- trimString(payload?.message) ||
69
- `Persona API request failed (${response.status})`;
70
- const error = new Error(errorMessage);
71
- error.status = response.status;
72
- error.payload = payload;
73
- throw error;
74
- }
75
-
76
- return payload;
77
- }
78
-
79
- export function createPersonaApiClient({
80
- backendUrl,
81
- deviceToken,
82
- deviceId,
83
- fetchImpl = globalThis.fetch,
84
- }) {
85
- if (typeof fetchImpl !== 'function') {
86
- throw new Error('fetch implementation is required.');
87
- }
88
-
89
- const resolvedBackendUrl = stripTrailingSlash(backendUrl);
90
- const resolvedDeviceToken = trimString(deviceToken);
91
- const resolvedDeviceId = trimString(deviceId);
92
-
93
- function withDevice(body = {}) {
94
- if (!resolvedDeviceId) {
95
- return body;
96
- }
97
- return {
98
- ...body,
99
- deviceId: resolvedDeviceId,
100
- };
101
- }
102
-
1
+ function trimString(value) {
2
+ return typeof value === 'string' ? value.trim() : '';
3
+ }
4
+
5
+ function stripTrailingSlash(value) {
6
+ return trimString(value).replace(/\/+$/, '');
7
+ }
8
+
9
+ async function readJsonResponse(response) {
10
+ return response.json().catch(() => ({}));
11
+ }
12
+
13
+ async function getJson({ fetchImpl, backendUrl, path, deviceToken }) {
14
+ const baseUrl = stripTrailingSlash(backendUrl);
15
+ if (!baseUrl) {
16
+ throw new Error('Backend URL is required.');
17
+ }
18
+
19
+ const headers = {};
20
+ const token = trimString(deviceToken);
21
+ if (token) {
22
+ headers.Authorization = `Bearer ${token}`;
23
+ }
24
+
25
+ const response = await fetchImpl(`${baseUrl}${path}`, {
26
+ method: 'GET',
27
+ headers,
28
+ });
29
+
30
+ const payload = await readJsonResponse(response);
31
+ if (!response.ok) {
32
+ const errorMessage =
33
+ trimString(payload?.error) ||
34
+ trimString(payload?.message) ||
35
+ `Persona API request failed (${response.status})`;
36
+ const error = new Error(errorMessage);
37
+ error.status = response.status;
38
+ error.payload = payload;
39
+ throw error;
40
+ }
41
+
42
+ return payload;
43
+ }
44
+
45
+ async function postJson({ fetchImpl, backendUrl, path, deviceToken, body }) {
46
+ const baseUrl = stripTrailingSlash(backendUrl);
47
+ if (!baseUrl) {
48
+ throw new Error('Backend URL is required.');
49
+ }
50
+ const token = trimString(deviceToken);
51
+ if (!token) {
52
+ throw new Error('Device token is required.');
53
+ }
54
+
55
+ const response = await fetchImpl(`${baseUrl}${path}`, {
56
+ method: 'POST',
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ Authorization: `Bearer ${token}`,
60
+ },
61
+ body: JSON.stringify(body),
62
+ });
63
+
64
+ const payload = await readJsonResponse(response);
65
+ if (!response.ok) {
66
+ const errorMessage =
67
+ trimString(payload?.error) ||
68
+ trimString(payload?.message) ||
69
+ `Persona API request failed (${response.status})`;
70
+ const error = new Error(errorMessage);
71
+ error.status = response.status;
72
+ error.payload = payload;
73
+ throw error;
74
+ }
75
+
76
+ return payload;
77
+ }
78
+
79
+ export function createPersonaApiClient({
80
+ backendUrl,
81
+ deviceToken,
82
+ fetchImpl = globalThis.fetch,
83
+ }) {
84
+ if (typeof fetchImpl !== 'function') {
85
+ throw new Error('fetch implementation is required.');
86
+ }
87
+
88
+ const resolvedBackendUrl = stripTrailingSlash(backendUrl);
89
+ const resolvedDeviceToken = trimString(deviceToken);
90
+
103
91
  return {
104
- listPersonas() {
92
+ listPersonaApps() {
105
93
  return getJson({
106
94
  fetchImpl,
107
95
  backendUrl: resolvedBackendUrl,
108
96
  deviceToken: resolvedDeviceToken,
109
- path: '/v1/personas',
97
+ path: '/v1/persona_apps',
110
98
  });
111
99
  },
112
100
 
113
- getPersona({
101
+ getPersonaApp({
114
102
  slug,
115
103
  }) {
116
- const safeSlug = trimString(slug);
117
- if (!safeSlug) {
118
- throw new Error('Persona slug is required.');
119
- }
120
-
121
- return getJson({
122
- fetchImpl,
123
- backendUrl: resolvedBackendUrl,
124
- deviceToken: resolvedDeviceToken,
125
- path: `/v1/personas/${encodeURIComponent(safeSlug)}`,
126
- });
127
- },
128
-
129
- createManagedPersona({
130
- slug,
131
- name,
132
- description,
133
- templateType = 'persona-app',
134
- promptTemplateVersion = 'v1',
135
- }) {
136
- const safeName = trimString(name);
137
- if (!safeName) {
138
- throw new Error('Persona name is required.');
139
- }
140
-
141
- const body = withDevice({
142
- name: safeName,
143
- description: trimString(description) || safeName,
144
- templateType: trimString(templateType) || 'persona-app',
145
- promptTemplateVersion: trimString(promptTemplateVersion) || 'v1',
146
- });
147
- const safeSlug = trimString(slug);
148
- if (safeSlug) {
149
- body.slug = safeSlug;
150
- }
151
-
152
- return postJson({
153
- fetchImpl,
154
- backendUrl: resolvedBackendUrl,
155
- deviceToken: resolvedDeviceToken,
156
- path: '/v1/personas/managed_create',
157
- body,
158
- });
159
- },
160
-
161
- registerRuntime({
162
- slug,
163
- endpoint,
164
- healthcheckUrl,
165
- transport = 'local',
166
- localPort,
167
- startedAt,
168
- }) {
169
- const safeSlug = trimString(slug);
170
- if (!safeSlug) {
171
- throw new Error('Persona slug is required.');
172
- }
173
-
174
- return postJson({
175
- fetchImpl,
176
- backendUrl: resolvedBackendUrl,
177
- deviceToken: resolvedDeviceToken,
178
- path: `/v1/personas/${encodeURIComponent(safeSlug)}/runtime_register`,
179
- body: withDevice({
180
- endpoint,
181
- healthcheckUrl,
182
- transport,
183
- localPort,
184
- startedAt,
185
- }),
186
- });
187
- },
188
-
189
- heartbeatRuntime({
190
- slug,
191
- endpoint,
192
- healthcheckUrl,
193
- transport = 'local',
194
- localPort,
195
- observedAt,
196
- }) {
197
- const safeSlug = trimString(slug);
198
- if (!safeSlug) {
199
- throw new Error('Persona slug is required.');
200
- }
201
-
202
- return postJson({
203
- fetchImpl,
204
- backendUrl: resolvedBackendUrl,
205
- deviceToken: resolvedDeviceToken,
206
- path: `/v1/personas/${encodeURIComponent(safeSlug)}/heartbeat`,
207
- body: withDevice({
208
- endpoint,
209
- healthcheckUrl,
210
- transport,
211
- localPort,
212
- observedAt,
213
- }),
214
- });
215
- },
216
-
217
- failRuntime({
218
- slug,
219
- code,
220
- message,
221
- }) {
222
- const safeSlug = trimString(slug);
223
- if (!safeSlug) {
224
- throw new Error('Persona slug is required.');
225
- }
226
-
227
- return postJson({
228
- fetchImpl,
229
- backendUrl: resolvedBackendUrl,
230
- deviceToken: resolvedDeviceToken,
231
- path: `/v1/personas/${encodeURIComponent(safeSlug)}/fail`,
232
- body: withDevice({
233
- code,
234
- message,
235
- }),
236
- });
237
- },
238
-
239
- startJob({
240
- jobId,
241
- startedAt,
242
- }) {
243
- const safeJobId = trimString(jobId);
244
- if (!safeJobId) {
245
- throw new Error('Persona job id is required.');
246
- }
247
-
248
- return postJson({
249
- fetchImpl,
250
- backendUrl: resolvedBackendUrl,
251
- deviceToken: resolvedDeviceToken,
252
- path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/start`,
253
- body: withDevice({
254
- startedAt,
255
- }),
256
- });
257
- },
258
-
259
- succeedJob({
260
- jobId,
261
- workspacePath,
262
- localPort,
263
- transport = 'local',
264
- endpoint,
265
- healthcheckUrl,
266
- completedAt,
267
- }) {
268
- const safeJobId = trimString(jobId);
269
- if (!safeJobId) {
270
- throw new Error('Persona job id is required.');
271
- }
272
-
273
- return postJson({
274
- fetchImpl,
275
- backendUrl: resolvedBackendUrl,
276
- deviceToken: resolvedDeviceToken,
277
- path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/succeed`,
278
- body: withDevice({
279
- workspacePath,
280
- localPort,
281
- transport,
282
- endpoint,
283
- healthcheckUrl,
284
- completedAt,
285
- }),
286
- });
287
- },
288
-
289
- failJob({
290
- jobId,
291
- code,
292
- message,
293
- completedAt,
294
- }) {
295
- const safeJobId = trimString(jobId);
296
- if (!safeJobId) {
297
- throw new Error('Persona job id is required.');
298
- }
299
-
300
- return postJson({
301
- fetchImpl,
302
- backendUrl: resolvedBackendUrl,
303
- deviceToken: resolvedDeviceToken,
304
- path: `/v1/persona_jobs/${encodeURIComponent(safeJobId)}/fail`,
305
- body: withDevice({
306
- code,
307
- message,
308
- completedAt,
309
- }),
310
- });
311
- },
312
- };
313
- }
104
+ const safeSlug = trimString(slug);
105
+ if (!safeSlug) {
106
+ throw new Error('Persona app slug is required.');
107
+ }
108
+
109
+ return getJson({
110
+ fetchImpl,
111
+ backendUrl: resolvedBackendUrl,
112
+ deviceToken: resolvedDeviceToken,
113
+ path: `/v1/persona_apps/${encodeURIComponent(safeSlug)}`,
114
+ });
115
+ },
116
+
117
+ applyPersonaAppAction({
118
+ slug,
119
+ actionId,
120
+ payload = {},
121
+ }) {
122
+ const safeSlug = trimString(slug);
123
+ if (!safeSlug) {
124
+ throw new Error('Persona app slug is required.');
125
+ }
126
+ const safeActionId = trimString(actionId);
127
+ if (!safeActionId) {
128
+ throw new Error('Persona app action id is required.');
129
+ }
130
+
131
+ return postJson({
132
+ fetchImpl,
133
+ backendUrl: resolvedBackendUrl,
134
+ deviceToken: resolvedDeviceToken,
135
+ path: `/v1/persona_apps/${encodeURIComponent(safeSlug)}/actions`,
136
+ body: {
137
+ actionId: safeActionId,
138
+ payload: payload && typeof payload === 'object' ? payload : {},
139
+ },
140
+ });
141
+ },
142
+ };
143
+ }