gestalt-mobile 0.16.2 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/index-DWHYFaoK.js +25 -0
- package/dist/client/index.html +1 -1
- package/dist/server/server/composition.js +1 -1
- package/dist/server/server/features/sessions/get-history/history-mapper.js +56 -5
- package/dist/server/server/features/sessions/start-turn/endpoint.js +1 -1
- package/dist/server/server/platform/codex/session-runtime.js +50 -1
- package/package.json +1 -1
- package/dist/client/assets/index-DT1VwqSF.js +0 -25
package/dist/client/index.html
CHANGED
|
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
16
16
|
<link rel="icon" href="/icons/gestalt-mobile-192.png" />
|
|
17
17
|
<link rel="apple-touch-icon" href="/icons/gestalt-mobile-180.png" />
|
|
18
18
|
<title>Gestalt Mobile</title>
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-DWHYFaoK.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-BotpWcLh.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
@@ -283,7 +283,7 @@ export async function composeRelayApp(options) {
|
|
|
283
283
|
? async (session, settings) => runtime.start(session, new Date().toISOString(), settings)
|
|
284
284
|
: undefined,
|
|
285
285
|
startTurn: runtime
|
|
286
|
-
? async (session, text) => runtime.startTurn(session, text, new Date().toISOString())
|
|
286
|
+
? async (session, text, clientUserMessageId) => runtime.startTurn(session, text, clientUserMessageId, new Date().toISOString())
|
|
287
287
|
: undefined,
|
|
288
288
|
onTurnStarted: (session) => planMeasurementRefresh?.refreshNow(session.id),
|
|
289
289
|
models,
|
|
@@ -34,7 +34,16 @@ function toChatItem(item, timestamp, turnId) {
|
|
|
34
34
|
.join('\n')
|
|
35
35
|
: '';
|
|
36
36
|
return text
|
|
37
|
-
? [
|
|
37
|
+
? [
|
|
38
|
+
{
|
|
39
|
+
id,
|
|
40
|
+
kind: 'user',
|
|
41
|
+
text,
|
|
42
|
+
...owner,
|
|
43
|
+
...(typeof item.clientId === 'string' ? { operationId: item.clientId } : {}),
|
|
44
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
45
|
+
},
|
|
46
|
+
]
|
|
38
47
|
: [];
|
|
39
48
|
}
|
|
40
49
|
case 'agentMessage':
|
|
@@ -48,7 +57,7 @@ function toChatItem(item, timestamp, turnId) {
|
|
|
48
57
|
...(item.phase === 'commentary' || item.phase === 'final_answer'
|
|
49
58
|
? { phase: item.phase }
|
|
50
59
|
: {}),
|
|
51
|
-
...(timestamp ? { occurredAt: timestamp } : {}),
|
|
60
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
52
61
|
},
|
|
53
62
|
]
|
|
54
63
|
: [];
|
|
@@ -56,10 +65,28 @@ function toChatItem(item, timestamp, turnId) {
|
|
|
56
65
|
if (!Array.isArray(item.summary))
|
|
57
66
|
return [];
|
|
58
67
|
const summary = reasoningSummary(item.summary);
|
|
59
|
-
return summary.length
|
|
68
|
+
return summary.length
|
|
69
|
+
? [
|
|
70
|
+
{
|
|
71
|
+
id,
|
|
72
|
+
kind: 'reasoning',
|
|
73
|
+
summary,
|
|
74
|
+
...owner,
|
|
75
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
: [];
|
|
60
79
|
case 'plan':
|
|
61
80
|
return typeof item.text === 'string'
|
|
62
|
-
? [
|
|
81
|
+
? [
|
|
82
|
+
{
|
|
83
|
+
id,
|
|
84
|
+
kind: 'plan',
|
|
85
|
+
text: item.text,
|
|
86
|
+
...owner,
|
|
87
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
88
|
+
},
|
|
89
|
+
]
|
|
63
90
|
: [];
|
|
64
91
|
case 'commandExecution':
|
|
65
92
|
return typeof item.command === 'string' && typeof item.status === 'string'
|
|
@@ -70,6 +97,7 @@ function toChatItem(item, timestamp, turnId) {
|
|
|
70
97
|
command: item.command,
|
|
71
98
|
status: item.status,
|
|
72
99
|
...owner,
|
|
100
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
73
101
|
...(typeof item.exitCode === 'number' ? { exitCode: item.exitCode } : {}),
|
|
74
102
|
},
|
|
75
103
|
]
|
|
@@ -79,9 +107,32 @@ function toChatItem(item, timestamp, turnId) {
|
|
|
79
107
|
return [];
|
|
80
108
|
const paths = item.changes.flatMap((change) => isRecord(change) && typeof change.path === 'string' ? [change.path] : []);
|
|
81
109
|
return paths.length
|
|
82
|
-
? [
|
|
110
|
+
? [
|
|
111
|
+
{
|
|
112
|
+
id,
|
|
113
|
+
kind: 'fileChange',
|
|
114
|
+
paths,
|
|
115
|
+
status: item.status,
|
|
116
|
+
...owner,
|
|
117
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
118
|
+
},
|
|
119
|
+
]
|
|
83
120
|
: [];
|
|
84
121
|
}
|
|
122
|
+
case 'mcpToolCall':
|
|
123
|
+
case 'dynamicToolCall':
|
|
124
|
+
return typeof item.tool === 'string' && typeof item.status === 'string'
|
|
125
|
+
? [
|
|
126
|
+
{
|
|
127
|
+
id,
|
|
128
|
+
kind: 'tool',
|
|
129
|
+
name: item.tool,
|
|
130
|
+
status: item.status,
|
|
131
|
+
...owner,
|
|
132
|
+
...(timestamp !== undefined ? { occurredAt: timestamp } : {}),
|
|
133
|
+
},
|
|
134
|
+
]
|
|
135
|
+
: [];
|
|
85
136
|
default:
|
|
86
137
|
return [];
|
|
87
138
|
}
|
|
@@ -28,7 +28,7 @@ export function registerStartTurn(app, deps) {
|
|
|
28
28
|
const inflightKey = `${scope}:${key}`;
|
|
29
29
|
const operation = inflight.get(inflightKey) ??
|
|
30
30
|
(async () => {
|
|
31
|
-
const started = await deps.start(session, text);
|
|
31
|
+
const started = await deps.start(session, text, key);
|
|
32
32
|
deps.save(started);
|
|
33
33
|
deps.onStarted?.(started);
|
|
34
34
|
const result = {
|
|
@@ -130,13 +130,14 @@ export class CodexSessionRuntime {
|
|
|
130
130
|
pending.resolve(result);
|
|
131
131
|
return true;
|
|
132
132
|
}
|
|
133
|
-
async startTurn(session, text, now) {
|
|
133
|
+
async startTurn(session, text, clientUserMessageId, now) {
|
|
134
134
|
const resource = this.sessions.get(session.id);
|
|
135
135
|
if (!resource || !session.threadId)
|
|
136
136
|
throw new Error('CODEX_SESSION_NOT_RUNNING');
|
|
137
137
|
const result = decodeTurnStart(await resource.process.rpc.request('turn/start', {
|
|
138
138
|
threadId: session.threadId,
|
|
139
139
|
input: [{ type: 'text', text, text_elements: [] }],
|
|
140
|
+
...(clientUserMessageId ? { clientUserMessageId } : {}),
|
|
140
141
|
...(session.model ? { model: session.model } : {}),
|
|
141
142
|
}));
|
|
142
143
|
return RelaySession.rehydrate(session).startTurn(result, now).snapshot;
|
|
@@ -433,6 +434,13 @@ function decodeHistoryItem(value) {
|
|
|
433
434
|
const type = boundedString(item?.type, 64);
|
|
434
435
|
if (!item || !id || !type)
|
|
435
436
|
return [];
|
|
437
|
+
if (type === 'userMessage') {
|
|
438
|
+
const content = decodeUserMessageContent(item.content);
|
|
439
|
+
if (!content.length)
|
|
440
|
+
return [];
|
|
441
|
+
const clientId = boundedString(item.clientId, 256);
|
|
442
|
+
return [{ id, type, content, ...(clientId ? { clientId } : {}) }];
|
|
443
|
+
}
|
|
436
444
|
if (type === 'agentMessage')
|
|
437
445
|
return [
|
|
438
446
|
{
|
|
@@ -442,6 +450,10 @@ function decodeHistoryItem(value) {
|
|
|
442
450
|
...(boundedString(item.phase, 64) ? { phase: boundedString(item.phase, 64) } : {}),
|
|
443
451
|
},
|
|
444
452
|
];
|
|
453
|
+
if (type === 'reasoning') {
|
|
454
|
+
const summary = decodeReasoningSummary(item.summary);
|
|
455
|
+
return summary.length ? [{ id, type, summary }] : [];
|
|
456
|
+
}
|
|
445
457
|
if (type === 'plan' && boundedString(item.text))
|
|
446
458
|
return [{ id, type, text: boundedString(item.text) }];
|
|
447
459
|
if (type === 'commandExecution' && boundedString(item.command) && boundedString(item.status, 64))
|
|
@@ -454,5 +466,42 @@ function decodeHistoryItem(value) {
|
|
|
454
466
|
...(typeof item.exitCode === 'number' ? { exitCode: item.exitCode } : {}),
|
|
455
467
|
},
|
|
456
468
|
];
|
|
469
|
+
if (type === 'fileChange') {
|
|
470
|
+
const changes = decodeFileChanges(item.changes);
|
|
471
|
+
const status = boundedString(item.status, 64);
|
|
472
|
+
return changes.length && status ? [{ id, type, changes, status }] : [];
|
|
473
|
+
}
|
|
474
|
+
if ((type === 'mcpToolCall' || type === 'dynamicToolCall') && boundedString(item.tool)) {
|
|
475
|
+
const status = boundedString(item.status, 64);
|
|
476
|
+
return status ? [{ id, type, tool: boundedString(item.tool), status }] : [];
|
|
477
|
+
}
|
|
457
478
|
return [];
|
|
458
479
|
}
|
|
480
|
+
function decodeUserMessageContent(value) {
|
|
481
|
+
if (!Array.isArray(value) || value.length > 1_000)
|
|
482
|
+
return [];
|
|
483
|
+
return value.flatMap((part) => {
|
|
484
|
+
const record = asRecord(part);
|
|
485
|
+
const text = boundedString(record?.text);
|
|
486
|
+
return record?.type === 'text' && text ? [{ type: 'text', text }] : [];
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
function decodeReasoningSummary(value) {
|
|
490
|
+
if (!Array.isArray(value) || value.length > 1_000)
|
|
491
|
+
return [];
|
|
492
|
+
return value.flatMap((part) => {
|
|
493
|
+
if (boundedString(part))
|
|
494
|
+
return [boundedString(part)];
|
|
495
|
+
const record = asRecord(part);
|
|
496
|
+
const text = boundedString(record?.text);
|
|
497
|
+
return record?.type === 'summary_text' && text ? [text] : [];
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
function decodeFileChanges(value) {
|
|
501
|
+
if (!Array.isArray(value) || value.length > 1_000)
|
|
502
|
+
return [];
|
|
503
|
+
return value.flatMap((change) => {
|
|
504
|
+
const path = boundedString(asRecord(change)?.path);
|
|
505
|
+
return path ? [{ path }] : [];
|
|
506
|
+
});
|
|
507
|
+
}
|