@beanx/cathygo-web-core 0.1.3 → 0.1.4
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 +8 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +139 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,10 +21,16 @@ Host applications still own account routing, agent selection, transport setup,
|
|
|
21
21
|
selected session id, lightweight session lists, and product-specific shell UI.
|
|
22
22
|
They should not own a second session execution runtime.
|
|
23
23
|
|
|
24
|
+
## Session Host Helpers (`@0.1.4`)
|
|
25
|
+
|
|
26
|
+
- `buildSessionLoadedAction` / `conversationMessagesToChatMessages`
|
|
27
|
+
- `createSessionEventRouter`
|
|
28
|
+
- `selectCanSend`, `selectCanStop`, `selectActiveTurnId`, `selectSessionStatus`, `selectIsMutating`
|
|
29
|
+
|
|
24
30
|
## First vNext Deliverables
|
|
25
31
|
|
|
26
32
|
- Keep the current single-session `ChatState` reducer exported.
|
|
27
|
-
-
|
|
33
|
+
- Session host helpers and selectors (above).
|
|
28
34
|
- Add reducer tests for interrupt, replay, stop, and optimistic reconciliation.
|
|
29
35
|
- Prove the implementation in `cathygo-agent/web` before publishing
|
|
30
|
-
|
|
36
|
+
npm bumps on the `0.1.x` line (`0.2.0` reserved for breaking renames).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { Dispatch, RefObject } from 'react';
|
|
3
|
-
import { AgentActivity, SessionRuntimeSnapshot, LearningTurnEvent, ConversationSummary, GatewayModelStatus } from '@beanx/cathygo-protocol';
|
|
3
|
+
import { AgentActivity, SessionRuntimeSnapshot, LearningTurnEvent, ConversationSummary, GatewayModelStatus, ConversationDetail, ConversationMessage } from '@beanx/cathygo-protocol';
|
|
4
4
|
|
|
5
5
|
type AgentIdentityStatus = {
|
|
6
6
|
agent_id?: string | null;
|
|
@@ -394,4 +394,34 @@ declare function ChatView({ chat, draft, attachments, attachmentPolicy, composer
|
|
|
394
394
|
|
|
395
395
|
declare function modelStatusText(model: GatewayModelStatus): string;
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
type RunningTurnsBySession = Record<string, string>;
|
|
398
|
+
declare function eventSessionId(event: LearningTurnEvent): string | undefined;
|
|
399
|
+
declare function eventTurnId(event: LearningTurnEvent): string | undefined;
|
|
400
|
+
declare function shouldApplyEventToRuntime(chat: ChatState | undefined, event: LearningTurnEvent): boolean;
|
|
401
|
+
declare function shouldApplyEventToActiveSession(event: LearningTurnEvent, activeSessionId: string | undefined): boolean;
|
|
402
|
+
declare function isChatStateMutating(chat: ChatState | undefined): boolean;
|
|
403
|
+
declare function selectCanSend(chat: ChatState): boolean;
|
|
404
|
+
declare function selectCanStop(chat: ChatState): boolean;
|
|
405
|
+
declare function selectActiveTurnId(chat: ChatState): string | undefined;
|
|
406
|
+
declare function selectSessionStatus(chat: ChatState): string;
|
|
407
|
+
declare function selectIsMutating(chat: ChatState): boolean;
|
|
408
|
+
declare function updateRunningTurnFromEvent(running: RunningTurnsBySession, event: LearningTurnEvent): RunningTurnsBySession;
|
|
409
|
+
declare function createSessionEventRouter(options: {
|
|
410
|
+
getActiveSessionId: () => string | undefined;
|
|
411
|
+
getChat: () => ChatState;
|
|
412
|
+
dispatchChat: (action: {
|
|
413
|
+
type: 'event.received';
|
|
414
|
+
event: LearningTurnEvent;
|
|
415
|
+
}) => void;
|
|
416
|
+
onTerminalTurn?: (sessionId: string) => void;
|
|
417
|
+
}): (event: LearningTurnEvent) => void;
|
|
418
|
+
|
|
419
|
+
type SessionHydrationOptions = {
|
|
420
|
+
resolveAttachmentUrl?: (uri: string) => string;
|
|
421
|
+
};
|
|
422
|
+
declare function buildSessionLoadedAction(sessionId: string, detail: ConversationDetail, options?: SessionHydrationOptions): Extract<ChatAction, {
|
|
423
|
+
type: 'session.loaded';
|
|
424
|
+
}>;
|
|
425
|
+
declare function conversationMessagesToChatMessages(messages: ConversationMessage[], options?: SessionHydrationOptions): ChatMessage$1[];
|
|
426
|
+
|
|
427
|
+
export { AgentActivityTimeline, type AgentIdentityStatus, type AgentRunProgress, type AgentRunProgressPhase, type AgentRunThinking, CHAT_HOME_MODES, CathyGOChatApp, type CathyGOChatAppProps, type CathyGOChatScreen, type ChatAction, ChatAgentIdentity, type ChatAttachment, type ChatHomeMode, type ChatHomeModeId, ChatHomeView, ChatListView, type ChatMessage$1 as ChatMessage, type ChatMessagePart, ChatMessage as ChatMessageView, type ChatRole, type ChatRuntimeId, ChatRuntimeSelector, type ChatRuntimeSelectorProps, type ChatState, ChatTopBar, ChatTranscript, ChatView, type ComposerAttachmentPolicy, type ComposerFileLike, type ComposerFileRejection, type ComposerFileRejectionReason, type ComposerFileValidationResult, DEFAULT_CHAT_HOME_MODE_ID, DEFAULT_COMPOSER_ATTACHMENT_POLICY, IconBack, IconBrain, IconCalendar, IconChevronDown, IconChevronRight, IconClose, IconCloud, IconCode, IconDevice, IconDevices, IconDocument, IconExternalLink, IconGatewayConnecting, IconGatewayOffline, IconGatewayOnline, IconGithub, IconHome, IconImageUpload, IconInfo, IconLocalComputer, IconMessage, IconMore, IconNewChat, IconPencil, IconPlug, IconSearch, IconSend, IconSettings, IconShield, IconSmartphone, MathMarkdown, MessageComposer, type MessageComposerHandle, type PendingComposerAttachment, RunStatus, type RunningTurnsBySession, type RuntimeOption, ScrollToBottomButton, type SessionHydrationOptions, type UseCathyGOChatResult, agentDisplayName, agentShortId, buildRuntimeOptions, buildSessionLoadedAction, composerAcceptAttribute, conversationMessagesToChatMessages, createSessionEventRouter, eventSessionId, eventTurnId, findChatHomeMode, fixCommonLatexMistakes, formatBytes, initialChatState, isChatStateMutating, modelStatusText, normalizeComposerAttachmentPolicy, normalizeMathDelimiters, prepareMathMarkdown, reduceChat, selectActiveTurnId, selectCanSend, selectCanStop, selectIsMutating, selectSessionStatus, shouldApplyEventToActiveSession, shouldApplyEventToRuntime, stripMathForPreview, updateRunningTurnFromEvent, useCathyGOChat, validateComposerFiles };
|
package/dist/index.js
CHANGED
|
@@ -2800,6 +2800,131 @@ function RuntimeIcon({ kind }) {
|
|
|
2800
2800
|
const className = "chat-runtime-icon";
|
|
2801
2801
|
return kind === "cloud" ? /* @__PURE__ */ jsx15(IconCloud, { className }) : /* @__PURE__ */ jsx15(IconLocalComputer, { className });
|
|
2802
2802
|
}
|
|
2803
|
+
|
|
2804
|
+
// src/session-host/session-runtime.ts
|
|
2805
|
+
var TERMINAL_TURN_EVENTS = /* @__PURE__ */ new Set(["turn.completed", "turn.failed", "turn.cancelled"]);
|
|
2806
|
+
function eventSessionId(event) {
|
|
2807
|
+
return optionalString2(event.payload.session_id);
|
|
2808
|
+
}
|
|
2809
|
+
function eventTurnId(event) {
|
|
2810
|
+
return optionalString2(event.payload.turn_id);
|
|
2811
|
+
}
|
|
2812
|
+
function shouldApplyEventToRuntime(chat, event) {
|
|
2813
|
+
const turnId = eventTurnId(event);
|
|
2814
|
+
if (!turnId || event.event === "session.input.accepted") return true;
|
|
2815
|
+
if (!isTurnScopedRuntimeEvent(event.event)) return true;
|
|
2816
|
+
const activeTurnId = chat?.activeTurnId;
|
|
2817
|
+
return !activeTurnId || activeTurnId === turnId;
|
|
2818
|
+
}
|
|
2819
|
+
function shouldApplyEventToActiveSession(event, activeSessionId) {
|
|
2820
|
+
const sessionId = eventSessionId(event);
|
|
2821
|
+
if (!sessionId) return false;
|
|
2822
|
+
if (!activeSessionId) return false;
|
|
2823
|
+
return sessionId === activeSessionId;
|
|
2824
|
+
}
|
|
2825
|
+
function isChatStateMutating(chat) {
|
|
2826
|
+
if (!chat) return false;
|
|
2827
|
+
return Boolean(chat.activeTurnId) || chat.status === "Sending" || chat.status === "Thinking" || chat.status === "Streaming" || chat.status === "Stopping";
|
|
2828
|
+
}
|
|
2829
|
+
function selectCanSend(chat) {
|
|
2830
|
+
return chat.status !== "Loading" && chat.status !== "Disconnected" && chat.status !== "Error";
|
|
2831
|
+
}
|
|
2832
|
+
function selectCanStop(chat) {
|
|
2833
|
+
return Boolean(chat.activeTurnId) || chat.status === "Thinking" || chat.status === "Streaming" || chat.status === "Stopping";
|
|
2834
|
+
}
|
|
2835
|
+
function selectActiveTurnId(chat) {
|
|
2836
|
+
return chat.activeTurnId;
|
|
2837
|
+
}
|
|
2838
|
+
function selectSessionStatus(chat) {
|
|
2839
|
+
return chat.status;
|
|
2840
|
+
}
|
|
2841
|
+
function selectIsMutating(chat) {
|
|
2842
|
+
return isChatStateMutating(chat);
|
|
2843
|
+
}
|
|
2844
|
+
function updateRunningTurnFromEvent(running, event) {
|
|
2845
|
+
const sessionId = eventSessionId(event);
|
|
2846
|
+
const turnId = eventTurnId(event);
|
|
2847
|
+
if (!sessionId || !turnId) return running;
|
|
2848
|
+
if (TERMINAL_TURN_EVENTS.has(event.event)) {
|
|
2849
|
+
if (!running[sessionId] || running[sessionId] === turnId) {
|
|
2850
|
+
const next = { ...running };
|
|
2851
|
+
delete next[sessionId];
|
|
2852
|
+
return next;
|
|
2853
|
+
}
|
|
2854
|
+
return running;
|
|
2855
|
+
}
|
|
2856
|
+
if (event.event === "turn.started" || event.event === "assistant.delta") {
|
|
2857
|
+
if (running[sessionId] === turnId) return running;
|
|
2858
|
+
return { ...running, [sessionId]: turnId };
|
|
2859
|
+
}
|
|
2860
|
+
return running;
|
|
2861
|
+
}
|
|
2862
|
+
function createSessionEventRouter(options) {
|
|
2863
|
+
return (event) => {
|
|
2864
|
+
const sessionId = eventSessionId(event);
|
|
2865
|
+
if (shouldApplyEventToActiveSession(event, options.getActiveSessionId()) && shouldApplyEventToRuntime(options.getChat(), event)) {
|
|
2866
|
+
options.dispatchChat({ type: "event.received", event });
|
|
2867
|
+
}
|
|
2868
|
+
if (sessionId && TERMINAL_TURN_EVENTS.has(event.event)) {
|
|
2869
|
+
options.onTerminalTurn?.(sessionId);
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
}
|
|
2873
|
+
function isTurnScopedRuntimeEvent(event) {
|
|
2874
|
+
return event === "turn.started" || event === "assistant.delta" || event === "assistant.completed" || event === "turn.completed" || event === "turn.cancelled" || event === "turn.failed" || event === "agent.activity.started" || event === "agent.activity.updated" || event === "agent.activity.completed" || event === "agent.progress.delta";
|
|
2875
|
+
}
|
|
2876
|
+
function optionalString2(value) {
|
|
2877
|
+
if (value === void 0 || value === null) return void 0;
|
|
2878
|
+
const text = String(value).trim();
|
|
2879
|
+
return text || void 0;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
// src/session-host/hydration.ts
|
|
2883
|
+
function buildSessionLoadedAction(sessionId, detail, options = {}) {
|
|
2884
|
+
return {
|
|
2885
|
+
type: "session.loaded",
|
|
2886
|
+
sessionId,
|
|
2887
|
+
messages: conversationMessagesToChatMessages(detail.messages, options),
|
|
2888
|
+
activities: detail.activities ?? [],
|
|
2889
|
+
runtime: detail.runtime ?? detail.session.runtime
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
function conversationMessagesToChatMessages(messages, options = {}) {
|
|
2893
|
+
return messages.map((message) => ({
|
|
2894
|
+
id: message.id,
|
|
2895
|
+
role: message.role,
|
|
2896
|
+
content: message.content,
|
|
2897
|
+
parts: normalizeMessageParts(message.parts, options.resolveAttachmentUrl),
|
|
2898
|
+
turnId: message.turn_id ?? void 0,
|
|
2899
|
+
clientInputId: messageMetadataString(message.metadata, "client_input_id"),
|
|
2900
|
+
clientTurnId: messageMetadataString(message.metadata, "client_turn_id"),
|
|
2901
|
+
status: "done"
|
|
2902
|
+
}));
|
|
2903
|
+
}
|
|
2904
|
+
function normalizeMessageParts(parts, resolveAttachmentUrl) {
|
|
2905
|
+
const normalized = parts?.map((part) => {
|
|
2906
|
+
if (part.type === "text" && part.text) {
|
|
2907
|
+
return { type: "text", text: part.text };
|
|
2908
|
+
}
|
|
2909
|
+
if (part.type === "image" && part.attachment_id && part.attachment) {
|
|
2910
|
+
const uri = part.attachment.uri;
|
|
2911
|
+
return {
|
|
2912
|
+
type: "image",
|
|
2913
|
+
attachment_id: part.attachment_id,
|
|
2914
|
+
attachment: {
|
|
2915
|
+
...part.attachment,
|
|
2916
|
+
uri: uri && resolveAttachmentUrl ? resolveAttachmentUrl(uri) : uri
|
|
2917
|
+
}
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
return void 0;
|
|
2921
|
+
}).filter((part) => Boolean(part));
|
|
2922
|
+
return normalized?.length ? normalized : void 0;
|
|
2923
|
+
}
|
|
2924
|
+
function messageMetadataString(metadata, key) {
|
|
2925
|
+
const value = metadata?.[key];
|
|
2926
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2927
|
+
}
|
|
2803
2928
|
export {
|
|
2804
2929
|
AgentActivityTimeline,
|
|
2805
2930
|
CHAT_HOME_MODES,
|
|
@@ -2851,17 +2976,31 @@ export {
|
|
|
2851
2976
|
agentDisplayName,
|
|
2852
2977
|
agentShortId,
|
|
2853
2978
|
buildRuntimeOptions,
|
|
2979
|
+
buildSessionLoadedAction,
|
|
2854
2980
|
composerAcceptAttribute,
|
|
2981
|
+
conversationMessagesToChatMessages,
|
|
2982
|
+
createSessionEventRouter,
|
|
2983
|
+
eventSessionId,
|
|
2984
|
+
eventTurnId,
|
|
2855
2985
|
findChatHomeMode,
|
|
2856
2986
|
fixCommonLatexMistakes,
|
|
2857
2987
|
formatBytes,
|
|
2858
2988
|
initialChatState,
|
|
2989
|
+
isChatStateMutating,
|
|
2859
2990
|
modelStatusText,
|
|
2860
2991
|
normalizeComposerAttachmentPolicy,
|
|
2861
2992
|
normalizeMathDelimiters,
|
|
2862
2993
|
prepareMathMarkdown,
|
|
2863
2994
|
reduceChat,
|
|
2995
|
+
selectActiveTurnId,
|
|
2996
|
+
selectCanSend,
|
|
2997
|
+
selectCanStop,
|
|
2998
|
+
selectIsMutating,
|
|
2999
|
+
selectSessionStatus,
|
|
3000
|
+
shouldApplyEventToActiveSession,
|
|
3001
|
+
shouldApplyEventToRuntime,
|
|
2864
3002
|
stripMathForPreview,
|
|
3003
|
+
updateRunningTurnFromEvent,
|
|
2865
3004
|
useCathyGOChat,
|
|
2866
3005
|
validateComposerFiles
|
|
2867
3006
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beanx/cathygo-web-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"./styles.css": "./dist/styles.css"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@beanx/cathygo-protocol": "0.1.
|
|
19
|
+
"@beanx/cathygo-protocol": "0.1.5",
|
|
20
20
|
"@streamdown/math": "^1.0.2",
|
|
21
21
|
"katex": "^0.16.47",
|
|
22
22
|
"streamdown": "^2.5.0"
|