@percena/weft-react 0.1.5-next.0 → 0.1.5-next.2
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/README.md +1 -1
- package/dist/index.cjs +81 -20
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +81 -20
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -19,6 +19,6 @@ function Support({ boot }: { boot: { server: string; token: string; sessionId: s
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
`{ server, token, sessionId }` comes from your backend's embed bootstrap
|
|
22
|
-
(
|
|
22
|
+
(`POST /v1/embed/sessions` via direct `fetch()`). Re-exports the full
|
|
23
23
|
`@weft/ui` + `@weft/local-chat` surface (including `EN_FALLBACK` and
|
|
24
24
|
`createFlitroEmbedRuntime`). Peers: `react`, `react-dom`.
|
package/dist/index.cjs
CHANGED
|
@@ -4177,8 +4177,19 @@ var TurnCard = React10.memo(function TurnCard2({
|
|
|
4177
4177
|
if (prev.isLastResponse !== next.isLastResponse) return false;
|
|
4178
4178
|
if (prev.displayMode !== next.displayMode) return false;
|
|
4179
4179
|
if (prev.annotationInteractionMode !== next.annotationInteractionMode) return false;
|
|
4180
|
-
if (prev.activities !== next.activities)
|
|
4181
|
-
|
|
4180
|
+
if (prev.activities !== next.activities) {
|
|
4181
|
+
if (prev.activities.length !== next.activities.length) return false;
|
|
4182
|
+
for (let i = 0; i < prev.activities.length; i++) {
|
|
4183
|
+
const pa = prev.activities[i], na = next.activities[i];
|
|
4184
|
+
if (pa.id !== na.id || pa.status !== na.status || pa.content !== na.content) return false;
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
if (prev.response !== next.response) {
|
|
4188
|
+
if (!prev.response !== !next.response) return false;
|
|
4189
|
+
if (prev.response && next.response) {
|
|
4190
|
+
if (prev.response.text !== next.response.text || prev.response.isStreaming !== next.response.isStreaming || prev.response.messageId !== next.response.messageId || prev.response.annotations?.length !== next.response.annotations?.length) return false;
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4182
4193
|
if (prev.openAnnotationRequest !== next.openAnnotationRequest) return false;
|
|
4183
4194
|
if (prev.hasActiveFollowUpAnnotations !== next.hasActiveFollowUpAnnotations) return false;
|
|
4184
4195
|
return prev.sessionId === next.sessionId && prev.turnId === next.turnId;
|
|
@@ -5438,6 +5449,24 @@ function handleTextDelta(state, event) {
|
|
|
5438
5449
|
const streamingIndex = findStreamingMessage(session.messages, event.turnId);
|
|
5439
5450
|
if (streamingIndex !== -1) {
|
|
5440
5451
|
const currentMsg = session.messages[streamingIndex];
|
|
5452
|
+
if (currentMsg.isIntermediate && !event.isIntermediate) {
|
|
5453
|
+
const closedSession = updateMessageAt(session, streamingIndex, {
|
|
5454
|
+
isStreaming: false
|
|
5455
|
+
});
|
|
5456
|
+
const newMessage2 = {
|
|
5457
|
+
id: generateMessageId2(),
|
|
5458
|
+
role: "assistant",
|
|
5459
|
+
content: event.delta,
|
|
5460
|
+
timestamp: event.timestamp ?? Date.now(),
|
|
5461
|
+
isStreaming: true,
|
|
5462
|
+
isPending: true,
|
|
5463
|
+
turnId: event.turnId
|
|
5464
|
+
};
|
|
5465
|
+
return {
|
|
5466
|
+
session: appendMessage(closedSession, newMessage2, false),
|
|
5467
|
+
streaming: { content: event.delta, turnId: event.turnId }
|
|
5468
|
+
};
|
|
5469
|
+
}
|
|
5441
5470
|
const updatedSession = updateMessageAt(session, streamingIndex, {
|
|
5442
5471
|
content: currentMsg.content + event.delta
|
|
5443
5472
|
});
|
|
@@ -5450,7 +5479,8 @@ function handleTextDelta(state, event) {
|
|
|
5450
5479
|
timestamp: event.timestamp ?? Date.now(),
|
|
5451
5480
|
isStreaming: true,
|
|
5452
5481
|
isPending: true,
|
|
5453
|
-
turnId: event.turnId
|
|
5482
|
+
turnId: event.turnId,
|
|
5483
|
+
...event.isIntermediate ? { isIntermediate: true } : {}
|
|
5454
5484
|
};
|
|
5455
5485
|
return {
|
|
5456
5486
|
session: appendMessage(session, newMessage, false),
|
|
@@ -5460,12 +5490,15 @@ function handleTextDelta(state, event) {
|
|
|
5460
5490
|
function handleTextComplete(state, event) {
|
|
5461
5491
|
const { session, streaming } = state;
|
|
5462
5492
|
let msgIndex = findStreamingMessage(session.messages, event.turnId);
|
|
5493
|
+
if (msgIndex !== -1 && event.isIntermediate && !session.messages[msgIndex].isIntermediate) {
|
|
5494
|
+
msgIndex = -1;
|
|
5495
|
+
}
|
|
5463
5496
|
if (msgIndex === -1) {
|
|
5464
5497
|
msgIndex = findAssistantMessage(session.messages, event.turnId);
|
|
5465
5498
|
}
|
|
5466
5499
|
if (msgIndex !== -1) {
|
|
5467
5500
|
const existingMsg = session.messages[msgIndex];
|
|
5468
|
-
if (!existingMsg.isStreaming && existingMsg.isIntermediate &&
|
|
5501
|
+
if (!existingMsg.isStreaming && existingMsg.isIntermediate && !existingMsg.isPending) {
|
|
5469
5502
|
msgIndex = -1;
|
|
5470
5503
|
}
|
|
5471
5504
|
}
|
|
@@ -6533,14 +6566,16 @@ function mapCoreEventToProcessorEvent(coreEvent, sessionId) {
|
|
|
6533
6566
|
type: "text_delta",
|
|
6534
6567
|
sessionId,
|
|
6535
6568
|
delta: coreEvent.text,
|
|
6536
|
-
turnId: coreEvent.turnId
|
|
6569
|
+
turnId: coreEvent.turnId,
|
|
6570
|
+
isIntermediate: true
|
|
6537
6571
|
};
|
|
6538
6572
|
case "reasoning":
|
|
6539
6573
|
return {
|
|
6540
6574
|
type: "text_complete",
|
|
6541
6575
|
sessionId,
|
|
6542
6576
|
text: coreEvent.text,
|
|
6543
|
-
turnId: coreEvent.turnId
|
|
6577
|
+
turnId: coreEvent.turnId,
|
|
6578
|
+
isIntermediate: true
|
|
6544
6579
|
};
|
|
6545
6580
|
case "permission_response":
|
|
6546
6581
|
return {
|
|
@@ -6580,7 +6615,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
|
|
|
6580
6615
|
sessionId,
|
|
6581
6616
|
delta: item.text,
|
|
6582
6617
|
turnId: item.turnId,
|
|
6583
|
-
timestamp
|
|
6618
|
+
timestamp,
|
|
6619
|
+
...item.type === "reasoning_delta" && { isIntermediate: true }
|
|
6584
6620
|
};
|
|
6585
6621
|
case "assistant_message":
|
|
6586
6622
|
case "reasoning":
|
|
@@ -6590,7 +6626,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
|
|
|
6590
6626
|
text: item.text,
|
|
6591
6627
|
turnId: item.turnId,
|
|
6592
6628
|
timestamp,
|
|
6593
|
-
messageId: item.messageId
|
|
6629
|
+
messageId: item.messageId,
|
|
6630
|
+
...item.type === "reasoning" && { isIntermediate: true }
|
|
6594
6631
|
};
|
|
6595
6632
|
case "tool_call":
|
|
6596
6633
|
return {
|
|
@@ -7266,6 +7303,17 @@ function useAgentChatSession(options) {
|
|
|
7266
7303
|
function useTimelineAgentChatSession(options) {
|
|
7267
7304
|
const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
|
|
7268
7305
|
const [timeline, setTimeline] = (0, import_react19.useState)([]);
|
|
7306
|
+
const [sessionState, setSessionState] = (0, import_react19.useState)(() => ({
|
|
7307
|
+
session: {
|
|
7308
|
+
id: runtime.sessionId,
|
|
7309
|
+
workspaceId,
|
|
7310
|
+
workspaceName,
|
|
7311
|
+
lastMessageAt: 0,
|
|
7312
|
+
messages: [],
|
|
7313
|
+
isProcessing: false
|
|
7314
|
+
},
|
|
7315
|
+
streaming: null
|
|
7316
|
+
}));
|
|
7269
7317
|
const [capabilityReport, setCapabilityReport] = (0, import_react19.useState)(null);
|
|
7270
7318
|
const [error, setError] = (0, import_react19.useState)(null);
|
|
7271
7319
|
const [isReconnecting, setIsReconnecting] = (0, import_react19.useState)(false);
|
|
@@ -7276,6 +7324,11 @@ function useTimelineAgentChatSession(options) {
|
|
|
7276
7324
|
const onEvent = (envelope) => {
|
|
7277
7325
|
lastCursorRef.current = { epoch: envelope.epoch, afterSeq: envelope.seq };
|
|
7278
7326
|
setTimeline((current) => mergeTimeline(current, [envelope]));
|
|
7327
|
+
if (isChatTranscriptTimelineEnvelope(envelope)) {
|
|
7328
|
+
setSessionState(
|
|
7329
|
+
(current) => processEvent(current, mapTimelineEnvelopeToProcessorEvent(envelope)).state
|
|
7330
|
+
);
|
|
7331
|
+
}
|
|
7279
7332
|
setIsReconnecting(false);
|
|
7280
7333
|
};
|
|
7281
7334
|
const onError = (err) => {
|
|
@@ -7290,6 +7343,16 @@ function useTimelineAgentChatSession(options) {
|
|
|
7290
7343
|
if (catchupAbort) return;
|
|
7291
7344
|
if (result.items.length > 0) {
|
|
7292
7345
|
setTimeline((current) => mergeTimeline(current, result.items));
|
|
7346
|
+
const chatEvents = result.items.filter(isChatTranscriptTimelineEnvelope).sort((a, b) => a.epoch !== b.epoch ? a.epoch.localeCompare(b.epoch) : a.seq - b.seq);
|
|
7347
|
+
if (chatEvents.length > 0) {
|
|
7348
|
+
setSessionState((current) => {
|
|
7349
|
+
let s = current;
|
|
7350
|
+
for (const env of chatEvents) {
|
|
7351
|
+
s = processEvent(s, mapTimelineEnvelopeToProcessorEvent(env)).state;
|
|
7352
|
+
}
|
|
7353
|
+
return s;
|
|
7354
|
+
});
|
|
7355
|
+
}
|
|
7293
7356
|
}
|
|
7294
7357
|
if (result.hasGap) {
|
|
7295
7358
|
setHasGap(true);
|
|
@@ -7328,25 +7391,23 @@ function useTimelineAgentChatSession(options) {
|
|
|
7328
7391
|
const respondToPermission = (0, import_react19.useCallback)(async (requestId, allowed, remember) => {
|
|
7329
7392
|
await runtime.commands.respondToPermission(requestId, allowed, remember);
|
|
7330
7393
|
}, [runtime]);
|
|
7331
|
-
const
|
|
7332
|
-
() =>
|
|
7333
|
-
|
|
7334
|
-
sessionId: runtime.sessionId,
|
|
7335
|
-
workspaceId,
|
|
7336
|
-
workspaceName,
|
|
7337
|
-
runtimeState: runtime.getState(),
|
|
7338
|
-
capabilityReport,
|
|
7339
|
-
error
|
|
7340
|
-
}),
|
|
7341
|
-
[timeline, runtime, workspaceId, workspaceName, capabilityReport, error]
|
|
7394
|
+
const turns = (0, import_react19.useMemo)(
|
|
7395
|
+
() => groupMessagesByTurn(sessionState.session.messages),
|
|
7396
|
+
[sessionState]
|
|
7342
7397
|
);
|
|
7398
|
+
const runtimeState = runtime.getState();
|
|
7399
|
+
const isRunning = runtimeState.status === "running" || runtimeState.status === "preflighting" || runtimeState.status === "starting" || runtimeState.status === "waiting_for_permission";
|
|
7343
7400
|
const isConnected = runtime.events.isConnected();
|
|
7344
7401
|
return {
|
|
7345
|
-
|
|
7402
|
+
session: sessionState.session,
|
|
7403
|
+
turns,
|
|
7346
7404
|
timeline,
|
|
7405
|
+
isRunning,
|
|
7347
7406
|
isConnected,
|
|
7348
7407
|
isReconnecting,
|
|
7349
7408
|
hasGap,
|
|
7409
|
+
capabilityReport,
|
|
7410
|
+
error,
|
|
7350
7411
|
sendMessage,
|
|
7351
7412
|
abort,
|
|
7352
7413
|
respondToPermission
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ export { CreateFlitroEmbedRuntimeOptions, createFlitroEmbedRuntime };
|
|
|
5
5
|
* useAgentSession — the official L1 runtime-configuration API.
|
|
6
6
|
*
|
|
7
7
|
* Wraps `createFlitroEmbedRuntime` in a hook: the host backend mints
|
|
8
|
-
* `{ server, token, sessionId }`
|
|
8
|
+
* `{ server, token, sessionId }` via `POST /v1/embed/sessions` and the
|
|
9
9
|
* component renders `<TimelineAgentChatPanel runtime={session.runtime} />`.
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -3261,6 +3261,8 @@ interface TextDeltaEvent {
|
|
|
3261
3261
|
turnId?: string;
|
|
3262
3262
|
/** Timestamp from canonical timeline for stable ordering */
|
|
3263
3263
|
timestamp?: number;
|
|
3264
|
+
/** When true, this delta belongs to a reasoning/thinking block (intermediate content). */
|
|
3265
|
+
isIntermediate?: boolean;
|
|
3264
3266
|
}
|
|
3265
3267
|
/**
|
|
3266
3268
|
* Text complete event - finalizes streaming text
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { CreateFlitroEmbedRuntimeOptions, createFlitroEmbedRuntime };
|
|
|
5
5
|
* useAgentSession — the official L1 runtime-configuration API.
|
|
6
6
|
*
|
|
7
7
|
* Wraps `createFlitroEmbedRuntime` in a hook: the host backend mints
|
|
8
|
-
* `{ server, token, sessionId }`
|
|
8
|
+
* `{ server, token, sessionId }` via `POST /v1/embed/sessions` and the
|
|
9
9
|
* component renders `<TimelineAgentChatPanel runtime={session.runtime} />`.
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -3261,6 +3261,8 @@ interface TextDeltaEvent {
|
|
|
3261
3261
|
turnId?: string;
|
|
3262
3262
|
/** Timestamp from canonical timeline for stable ordering */
|
|
3263
3263
|
timestamp?: number;
|
|
3264
|
+
/** When true, this delta belongs to a reasoning/thinking block (intermediate content). */
|
|
3265
|
+
isIntermediate?: boolean;
|
|
3264
3266
|
}
|
|
3265
3267
|
/**
|
|
3266
3268
|
* Text complete event - finalizes streaming text
|
package/dist/index.js
CHANGED
|
@@ -4100,8 +4100,19 @@ var TurnCard = React10.memo(function TurnCard2({
|
|
|
4100
4100
|
if (prev.isLastResponse !== next.isLastResponse) return false;
|
|
4101
4101
|
if (prev.displayMode !== next.displayMode) return false;
|
|
4102
4102
|
if (prev.annotationInteractionMode !== next.annotationInteractionMode) return false;
|
|
4103
|
-
if (prev.activities !== next.activities)
|
|
4104
|
-
|
|
4103
|
+
if (prev.activities !== next.activities) {
|
|
4104
|
+
if (prev.activities.length !== next.activities.length) return false;
|
|
4105
|
+
for (let i = 0; i < prev.activities.length; i++) {
|
|
4106
|
+
const pa = prev.activities[i], na = next.activities[i];
|
|
4107
|
+
if (pa.id !== na.id || pa.status !== na.status || pa.content !== na.content) return false;
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
if (prev.response !== next.response) {
|
|
4111
|
+
if (!prev.response !== !next.response) return false;
|
|
4112
|
+
if (prev.response && next.response) {
|
|
4113
|
+
if (prev.response.text !== next.response.text || prev.response.isStreaming !== next.response.isStreaming || prev.response.messageId !== next.response.messageId || prev.response.annotations?.length !== next.response.annotations?.length) return false;
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4105
4116
|
if (prev.openAnnotationRequest !== next.openAnnotationRequest) return false;
|
|
4106
4117
|
if (prev.hasActiveFollowUpAnnotations !== next.hasActiveFollowUpAnnotations) return false;
|
|
4107
4118
|
return prev.sessionId === next.sessionId && prev.turnId === next.turnId;
|
|
@@ -5361,6 +5372,24 @@ function handleTextDelta(state, event) {
|
|
|
5361
5372
|
const streamingIndex = findStreamingMessage(session.messages, event.turnId);
|
|
5362
5373
|
if (streamingIndex !== -1) {
|
|
5363
5374
|
const currentMsg = session.messages[streamingIndex];
|
|
5375
|
+
if (currentMsg.isIntermediate && !event.isIntermediate) {
|
|
5376
|
+
const closedSession = updateMessageAt(session, streamingIndex, {
|
|
5377
|
+
isStreaming: false
|
|
5378
|
+
});
|
|
5379
|
+
const newMessage2 = {
|
|
5380
|
+
id: generateMessageId2(),
|
|
5381
|
+
role: "assistant",
|
|
5382
|
+
content: event.delta,
|
|
5383
|
+
timestamp: event.timestamp ?? Date.now(),
|
|
5384
|
+
isStreaming: true,
|
|
5385
|
+
isPending: true,
|
|
5386
|
+
turnId: event.turnId
|
|
5387
|
+
};
|
|
5388
|
+
return {
|
|
5389
|
+
session: appendMessage(closedSession, newMessage2, false),
|
|
5390
|
+
streaming: { content: event.delta, turnId: event.turnId }
|
|
5391
|
+
};
|
|
5392
|
+
}
|
|
5364
5393
|
const updatedSession = updateMessageAt(session, streamingIndex, {
|
|
5365
5394
|
content: currentMsg.content + event.delta
|
|
5366
5395
|
});
|
|
@@ -5373,7 +5402,8 @@ function handleTextDelta(state, event) {
|
|
|
5373
5402
|
timestamp: event.timestamp ?? Date.now(),
|
|
5374
5403
|
isStreaming: true,
|
|
5375
5404
|
isPending: true,
|
|
5376
|
-
turnId: event.turnId
|
|
5405
|
+
turnId: event.turnId,
|
|
5406
|
+
...event.isIntermediate ? { isIntermediate: true } : {}
|
|
5377
5407
|
};
|
|
5378
5408
|
return {
|
|
5379
5409
|
session: appendMessage(session, newMessage, false),
|
|
@@ -5383,12 +5413,15 @@ function handleTextDelta(state, event) {
|
|
|
5383
5413
|
function handleTextComplete(state, event) {
|
|
5384
5414
|
const { session, streaming } = state;
|
|
5385
5415
|
let msgIndex = findStreamingMessage(session.messages, event.turnId);
|
|
5416
|
+
if (msgIndex !== -1 && event.isIntermediate && !session.messages[msgIndex].isIntermediate) {
|
|
5417
|
+
msgIndex = -1;
|
|
5418
|
+
}
|
|
5386
5419
|
if (msgIndex === -1) {
|
|
5387
5420
|
msgIndex = findAssistantMessage(session.messages, event.turnId);
|
|
5388
5421
|
}
|
|
5389
5422
|
if (msgIndex !== -1) {
|
|
5390
5423
|
const existingMsg = session.messages[msgIndex];
|
|
5391
|
-
if (!existingMsg.isStreaming && existingMsg.isIntermediate &&
|
|
5424
|
+
if (!existingMsg.isStreaming && existingMsg.isIntermediate && !existingMsg.isPending) {
|
|
5392
5425
|
msgIndex = -1;
|
|
5393
5426
|
}
|
|
5394
5427
|
}
|
|
@@ -6456,14 +6489,16 @@ function mapCoreEventToProcessorEvent(coreEvent, sessionId) {
|
|
|
6456
6489
|
type: "text_delta",
|
|
6457
6490
|
sessionId,
|
|
6458
6491
|
delta: coreEvent.text,
|
|
6459
|
-
turnId: coreEvent.turnId
|
|
6492
|
+
turnId: coreEvent.turnId,
|
|
6493
|
+
isIntermediate: true
|
|
6460
6494
|
};
|
|
6461
6495
|
case "reasoning":
|
|
6462
6496
|
return {
|
|
6463
6497
|
type: "text_complete",
|
|
6464
6498
|
sessionId,
|
|
6465
6499
|
text: coreEvent.text,
|
|
6466
|
-
turnId: coreEvent.turnId
|
|
6500
|
+
turnId: coreEvent.turnId,
|
|
6501
|
+
isIntermediate: true
|
|
6467
6502
|
};
|
|
6468
6503
|
case "permission_response":
|
|
6469
6504
|
return {
|
|
@@ -6503,7 +6538,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
|
|
|
6503
6538
|
sessionId,
|
|
6504
6539
|
delta: item.text,
|
|
6505
6540
|
turnId: item.turnId,
|
|
6506
|
-
timestamp
|
|
6541
|
+
timestamp,
|
|
6542
|
+
...item.type === "reasoning_delta" && { isIntermediate: true }
|
|
6507
6543
|
};
|
|
6508
6544
|
case "assistant_message":
|
|
6509
6545
|
case "reasoning":
|
|
@@ -6513,7 +6549,8 @@ function mapTimelineEnvelopeToProcessorEvent(envelope) {
|
|
|
6513
6549
|
text: item.text,
|
|
6514
6550
|
turnId: item.turnId,
|
|
6515
6551
|
timestamp,
|
|
6516
|
-
messageId: item.messageId
|
|
6552
|
+
messageId: item.messageId,
|
|
6553
|
+
...item.type === "reasoning" && { isIntermediate: true }
|
|
6517
6554
|
};
|
|
6518
6555
|
case "tool_call":
|
|
6519
6556
|
return {
|
|
@@ -7189,6 +7226,17 @@ function useAgentChatSession(options) {
|
|
|
7189
7226
|
function useTimelineAgentChatSession(options) {
|
|
7190
7227
|
const { runtime, workspaceId = "local-workspace", workspaceName = "Local Workspace" } = options;
|
|
7191
7228
|
const [timeline, setTimeline] = useState12([]);
|
|
7229
|
+
const [sessionState, setSessionState] = useState12(() => ({
|
|
7230
|
+
session: {
|
|
7231
|
+
id: runtime.sessionId,
|
|
7232
|
+
workspaceId,
|
|
7233
|
+
workspaceName,
|
|
7234
|
+
lastMessageAt: 0,
|
|
7235
|
+
messages: [],
|
|
7236
|
+
isProcessing: false
|
|
7237
|
+
},
|
|
7238
|
+
streaming: null
|
|
7239
|
+
}));
|
|
7192
7240
|
const [capabilityReport, setCapabilityReport] = useState12(null);
|
|
7193
7241
|
const [error, setError] = useState12(null);
|
|
7194
7242
|
const [isReconnecting, setIsReconnecting] = useState12(false);
|
|
@@ -7199,6 +7247,11 @@ function useTimelineAgentChatSession(options) {
|
|
|
7199
7247
|
const onEvent = (envelope) => {
|
|
7200
7248
|
lastCursorRef.current = { epoch: envelope.epoch, afterSeq: envelope.seq };
|
|
7201
7249
|
setTimeline((current) => mergeTimeline(current, [envelope]));
|
|
7250
|
+
if (isChatTranscriptTimelineEnvelope(envelope)) {
|
|
7251
|
+
setSessionState(
|
|
7252
|
+
(current) => processEvent(current, mapTimelineEnvelopeToProcessorEvent(envelope)).state
|
|
7253
|
+
);
|
|
7254
|
+
}
|
|
7202
7255
|
setIsReconnecting(false);
|
|
7203
7256
|
};
|
|
7204
7257
|
const onError = (err) => {
|
|
@@ -7213,6 +7266,16 @@ function useTimelineAgentChatSession(options) {
|
|
|
7213
7266
|
if (catchupAbort) return;
|
|
7214
7267
|
if (result.items.length > 0) {
|
|
7215
7268
|
setTimeline((current) => mergeTimeline(current, result.items));
|
|
7269
|
+
const chatEvents = result.items.filter(isChatTranscriptTimelineEnvelope).sort((a, b) => a.epoch !== b.epoch ? a.epoch.localeCompare(b.epoch) : a.seq - b.seq);
|
|
7270
|
+
if (chatEvents.length > 0) {
|
|
7271
|
+
setSessionState((current) => {
|
|
7272
|
+
let s = current;
|
|
7273
|
+
for (const env of chatEvents) {
|
|
7274
|
+
s = processEvent(s, mapTimelineEnvelopeToProcessorEvent(env)).state;
|
|
7275
|
+
}
|
|
7276
|
+
return s;
|
|
7277
|
+
});
|
|
7278
|
+
}
|
|
7216
7279
|
}
|
|
7217
7280
|
if (result.hasGap) {
|
|
7218
7281
|
setHasGap(true);
|
|
@@ -7251,25 +7314,23 @@ function useTimelineAgentChatSession(options) {
|
|
|
7251
7314
|
const respondToPermission = useCallback9(async (requestId, allowed, remember) => {
|
|
7252
7315
|
await runtime.commands.respondToPermission(requestId, allowed, remember);
|
|
7253
7316
|
}, [runtime]);
|
|
7254
|
-
const
|
|
7255
|
-
() =>
|
|
7256
|
-
|
|
7257
|
-
sessionId: runtime.sessionId,
|
|
7258
|
-
workspaceId,
|
|
7259
|
-
workspaceName,
|
|
7260
|
-
runtimeState: runtime.getState(),
|
|
7261
|
-
capabilityReport,
|
|
7262
|
-
error
|
|
7263
|
-
}),
|
|
7264
|
-
[timeline, runtime, workspaceId, workspaceName, capabilityReport, error]
|
|
7317
|
+
const turns = useMemo8(
|
|
7318
|
+
() => groupMessagesByTurn(sessionState.session.messages),
|
|
7319
|
+
[sessionState]
|
|
7265
7320
|
);
|
|
7321
|
+
const runtimeState = runtime.getState();
|
|
7322
|
+
const isRunning = runtimeState.status === "running" || runtimeState.status === "preflighting" || runtimeState.status === "starting" || runtimeState.status === "waiting_for_permission";
|
|
7266
7323
|
const isConnected = runtime.events.isConnected();
|
|
7267
7324
|
return {
|
|
7268
|
-
|
|
7325
|
+
session: sessionState.session,
|
|
7326
|
+
turns,
|
|
7269
7327
|
timeline,
|
|
7328
|
+
isRunning,
|
|
7270
7329
|
isConnected,
|
|
7271
7330
|
isReconnecting,
|
|
7272
7331
|
hasGap,
|
|
7332
|
+
capabilityReport,
|
|
7333
|
+
error,
|
|
7273
7334
|
sendMessage,
|
|
7274
7335
|
abort,
|
|
7275
7336
|
respondToPermission
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percena/weft-react",
|
|
3
|
-
"version": "0.1.5-next.
|
|
3
|
+
"version": "0.1.5-next.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Weft React — TimelineAgentChatPanel + headless hooks (useAgentSession) with precompiled CSS; no Tailwind setup required in the host",
|
|
6
6
|
"type": "module",
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
"remark-gfm": "^4.0.0",
|
|
48
48
|
"remark-math": "^6.0.0",
|
|
49
49
|
"zod": "^3.0.0",
|
|
50
|
-
"@percena/weft-client": "^0.
|
|
50
|
+
"@percena/weft-client": "^0.2.0-next.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@tailwindcss/cli": "^4.0.0",
|
|
54
54
|
"@tailwindcss/typography": "^0.5.16",
|
|
55
55
|
"@types/react": "^19.2.14",
|
|
56
56
|
"tailwindcss": "^4.0.0",
|
|
57
|
-
"@weft/provider-flitro": "0.1.0",
|
|
58
|
-
"@weft/ui": "0.1.0",
|
|
59
57
|
"@weft/local-chat": "0.1.0",
|
|
60
|
-
"@weft/runtime-core": "0.1.0"
|
|
58
|
+
"@weft/runtime-core": "0.1.0",
|
|
59
|
+
"@weft/provider-flitro": "0.1.0",
|
|
60
|
+
"@weft/ui": "0.1.0"
|
|
61
61
|
},
|
|
62
62
|
"keywords": [
|
|
63
63
|
"weft",
|