@jini-ai/chat 0.1.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.
- package/LICENSE +201 -0
- package/README.md +109 -0
- package/dist/core/agentic/chat-capabilities.d.ts +19 -0
- package/dist/core/agentic/chat-capabilities.d.ts.map +1 -0
- package/dist/core/agentic/chat-capabilities.js +106 -0
- package/dist/core/agentic/chat-capabilities.js.map +1 -0
- package/dist/core/agentic/index.d.ts +22 -0
- package/dist/core/agentic/index.d.ts.map +1 -0
- package/dist/core/agentic/index.js +21 -0
- package/dist/core/agentic/index.js.map +1 -0
- package/dist/core/events.d.ts +84 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +14 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +40 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/messages.d.ts +53 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +16 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/partial-json.d.ts +36 -0
- package/dist/core/partial-json.d.ts.map +1 -0
- package/dist/core/partial-json.js +119 -0
- package/dist/core/partial-json.js.map +1 -0
- package/dist/core/persistence/index.d.ts +11 -0
- package/dist/core/persistence/index.d.ts.map +1 -0
- package/dist/core/persistence/index.js +11 -0
- package/dist/core/persistence/index.js.map +1 -0
- package/dist/core/persistence/ports.d.ts +124 -0
- package/dist/core/persistence/ports.d.ts.map +1 -0
- package/dist/core/persistence/ports.js +2 -0
- package/dist/core/persistence/ports.js.map +1 -0
- package/dist/core/persistence/title.d.ts +35 -0
- package/dist/core/persistence/title.d.ts.map +1 -0
- package/dist/core/persistence/title.js +137 -0
- package/dist/core/persistence/title.js.map +1 -0
- package/dist/core/question-form/format.d.ts +27 -0
- package/dist/core/question-form/format.d.ts.map +1 -0
- package/dist/core/question-form/format.js +45 -0
- package/dist/core/question-form/format.js.map +1 -0
- package/dist/core/question-form/normalize.d.ts +30 -0
- package/dist/core/question-form/normalize.d.ts.map +1 -0
- package/dist/core/question-form/normalize.js +192 -0
- package/dist/core/question-form/normalize.js.map +1 -0
- package/dist/core/question-form/scan.d.ts +50 -0
- package/dist/core/question-form/scan.d.ts.map +1 -0
- package/dist/core/question-form/scan.js +404 -0
- package/dist/core/question-form/scan.js.map +1 -0
- package/dist/core/question-form/types.d.ts +83 -0
- package/dist/core/question-form/types.d.ts.map +1 -0
- package/dist/core/question-form/types.js +11 -0
- package/dist/core/question-form/types.js.map +1 -0
- package/dist/core/question-form.d.ts +39 -0
- package/dist/core/question-form.d.ts.map +1 -0
- package/dist/core/question-form.js +4 -0
- package/dist/core/question-form.js.map +1 -0
- package/dist/core/todos.d.ts +70 -0
- package/dist/core/todos.d.ts.map +1 -0
- package/dist/core/todos.js +175 -0
- package/dist/core/todos.js.map +1 -0
- package/dist/core/tool-events.d.ts +18 -0
- package/dist/core/tool-events.d.ts.map +1 -0
- package/dist/core/tool-events.js +36 -0
- package/dist/core/tool-events.js.map +1 -0
- package/dist/core/tools.d.ts +51 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +41 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/core/transcript.d.ts +81 -0
- package/dist/core/transcript.d.ts.map +1 -0
- package/dist/core/transcript.js +133 -0
- package/dist/core/transcript.js.map +1 -0
- package/dist/core/transport.d.ts +109 -0
- package/dist/core/transport.d.ts.map +1 -0
- package/dist/core/transport.js +2 -0
- package/dist/core/transport.js.map +1 -0
- package/dist/core/util/index.d.ts +16 -0
- package/dist/core/util/index.d.ts.map +1 -0
- package/dist/core/util/index.js +16 -0
- package/dist/core/util/index.js.map +1 -0
- package/dist/core/util/manifest.d.ts +39 -0
- package/dist/core/util/manifest.d.ts.map +1 -0
- package/dist/core/util/manifest.js +173 -0
- package/dist/core/util/manifest.js.map +1 -0
- package/dist/core/util/markdown-context.d.ts +47 -0
- package/dist/core/util/markdown-context.d.ts.map +1 -0
- package/dist/core/util/markdown-context.js +125 -0
- package/dist/core/util/markdown-context.js.map +1 -0
- package/dist/core/util/markup-attributes.d.ts +20 -0
- package/dist/core/util/markup-attributes.d.ts.map +1 -0
- package/dist/core/util/markup-attributes.js +33 -0
- package/dist/core/util/markup-attributes.js.map +1 -0
- package/dist/core/util/parser.d.ts +42 -0
- package/dist/core/util/parser.d.ts.map +1 -0
- package/dist/core/util/parser.js +238 -0
- package/dist/core/util/parser.js.map +1 -0
- package/dist/core/util/pointer.d.ts +28 -0
- package/dist/core/util/pointer.d.ts.map +1 -0
- package/dist/core/util/pointer.js +75 -0
- package/dist/core/util/pointer.js.map +1 -0
- package/dist/core/util/recover.d.ts +40 -0
- package/dist/core/util/recover.d.ts.map +1 -0
- package/dist/core/util/recover.js +117 -0
- package/dist/core/util/recover.js.map +1 -0
- package/dist/core/util/strip.d.ts +112 -0
- package/dist/core/util/strip.d.ts.map +1 -0
- package/dist/core/util/strip.js +333 -0
- package/dist/core/util/strip.js.map +1 -0
- package/dist/core/util/types.d.ts +31 -0
- package/dist/core/util/types.d.ts.map +1 -0
- package/dist/core/util/types.js +2 -0
- package/dist/core/util/types.js.map +1 -0
- package/dist/core/util/validate.d.ts +50 -0
- package/dist/core/util/validate.d.ts.map +1 -0
- package/dist/core/util/validate.js +202 -0
- package/dist/core/util/validate.js.map +1 -0
- package/dist/react/agent-bridge/frontend-session-bridge.d.ts +45 -0
- package/dist/react/agent-bridge/frontend-session-bridge.d.ts.map +1 -0
- package/dist/react/agent-bridge/frontend-session-bridge.js +214 -0
- package/dist/react/agent-bridge/frontend-session-bridge.js.map +1 -0
- package/dist/react/artifact-types.d.ts +61 -0
- package/dist/react/artifact-types.d.ts.map +1 -0
- package/dist/react/artifact-types.js +33 -0
- package/dist/react/artifact-types.js.map +1 -0
- package/dist/react/chat-pane.d.ts +21 -0
- package/dist/react/chat-pane.d.ts.map +1 -0
- package/dist/react/chat-pane.js +20 -0
- package/dist/react/chat-pane.js.map +1 -0
- package/dist/react/components/A2uiSurfaceCard.d.ts +35 -0
- package/dist/react/components/A2uiSurfaceCard.d.ts.map +1 -0
- package/dist/react/components/A2uiSurfaceCard.js +272 -0
- package/dist/react/components/A2uiSurfaceCard.js.map +1 -0
- package/dist/react/components/AttachmentTray.d.ts +6 -0
- package/dist/react/components/AttachmentTray.d.ts.map +1 -0
- package/dist/react/components/AttachmentTray.js +30 -0
- package/dist/react/components/AttachmentTray.js.map +1 -0
- package/dist/react/components/ChatFab.d.ts +8 -0
- package/dist/react/components/ChatFab.d.ts.map +1 -0
- package/dist/react/components/ChatFab.js +24 -0
- package/dist/react/components/ChatFab.js.map +1 -0
- package/dist/react/components/Composer.d.ts +34 -0
- package/dist/react/components/Composer.d.ts.map +1 -0
- package/dist/react/components/Composer.js +300 -0
- package/dist/react/components/Composer.js.map +1 -0
- package/dist/react/components/ComposerDiscovery.d.ts +46 -0
- package/dist/react/components/ComposerDiscovery.d.ts.map +1 -0
- package/dist/react/components/ComposerDiscovery.js +38 -0
- package/dist/react/components/ComposerDiscovery.js.map +1 -0
- package/dist/react/components/ConversationList.d.ts +31 -0
- package/dist/react/components/ConversationList.d.ts.map +1 -0
- package/dist/react/components/ConversationList.js +221 -0
- package/dist/react/components/ConversationList.js.map +1 -0
- package/dist/react/components/ExtEventErrorBoundary.d.ts +35 -0
- package/dist/react/components/ExtEventErrorBoundary.d.ts.map +1 -0
- package/dist/react/components/ExtEventErrorBoundary.js +38 -0
- package/dist/react/components/ExtEventErrorBoundary.js.map +1 -0
- package/dist/react/components/Icon.d.ts +17 -0
- package/dist/react/components/Icon.d.ts.map +1 -0
- package/dist/react/components/Icon.js +46 -0
- package/dist/react/components/Icon.js.map +1 -0
- package/dist/react/components/JiniChatProvider.d.ts +45 -0
- package/dist/react/components/JiniChatProvider.d.ts.map +1 -0
- package/dist/react/components/JiniChatProvider.js +44 -0
- package/dist/react/components/JiniChatProvider.js.map +1 -0
- package/dist/react/components/Markdown.d.ts +5 -0
- package/dist/react/components/Markdown.d.ts.map +1 -0
- package/dist/react/components/Markdown.js +390 -0
- package/dist/react/components/Markdown.js.map +1 -0
- package/dist/react/components/McpUiSurfaceCard.d.ts +51 -0
- package/dist/react/components/McpUiSurfaceCard.d.ts.map +1 -0
- package/dist/react/components/McpUiSurfaceCard.js +159 -0
- package/dist/react/components/McpUiSurfaceCard.js.map +1 -0
- package/dist/react/components/MessageList.d.ts +15 -0
- package/dist/react/components/MessageList.d.ts.map +1 -0
- package/dist/react/components/MessageList.js +81 -0
- package/dist/react/components/MessageList.js.map +1 -0
- package/dist/react/components/MessageRow.d.ts +60 -0
- package/dist/react/components/MessageRow.d.ts.map +1 -0
- package/dist/react/components/MessageRow.js +156 -0
- package/dist/react/components/MessageRow.js.map +1 -0
- package/dist/react/components/NextStepActions.d.ts +34 -0
- package/dist/react/components/NextStepActions.d.ts.map +1 -0
- package/dist/react/components/NextStepActions.js +9 -0
- package/dist/react/components/NextStepActions.js.map +1 -0
- package/dist/react/components/QuestionForm.d.ts +26 -0
- package/dist/react/components/QuestionForm.d.ts.map +1 -0
- package/dist/react/components/QuestionForm.js +238 -0
- package/dist/react/components/QuestionForm.js.map +1 -0
- package/dist/react/components/QuestionsPanel.d.ts +13 -0
- package/dist/react/components/QuestionsPanel.d.ts.map +1 -0
- package/dist/react/components/QuestionsPanel.js +33 -0
- package/dist/react/components/QuestionsPanel.js.map +1 -0
- package/dist/react/components/TodoCard.d.ts +8 -0
- package/dist/react/components/TodoCard.d.ts.map +1 -0
- package/dist/react/components/TodoCard.js +29 -0
- package/dist/react/components/TodoCard.js.map +1 -0
- package/dist/react/components/ToolCard.d.ts +22 -0
- package/dist/react/components/ToolCard.d.ts.map +1 -0
- package/dist/react/components/ToolCard.js +298 -0
- package/dist/react/components/ToolCard.js.map +1 -0
- package/dist/react/components/composer-discovery.d.ts +107 -0
- package/dist/react/components/composer-discovery.d.ts.map +1 -0
- package/dist/react/components/composer-discovery.js +176 -0
- package/dist/react/components/composer-discovery.js.map +1 -0
- package/dist/react/ext-event-renderer-registry.d.ts +51 -0
- package/dist/react/ext-event-renderer-registry.d.ts.map +1 -0
- package/dist/react/ext-event-renderer-registry.js +20 -0
- package/dist/react/ext-event-renderer-registry.js.map +1 -0
- package/dist/react/features/chat-pane/agent-tools.d.ts +14 -0
- package/dist/react/features/chat-pane/agent-tools.d.ts.map +1 -0
- package/dist/react/features/chat-pane/agent-tools.js +22 -0
- package/dist/react/features/chat-pane/agent-tools.js.map +1 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts +12 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.d.ts.map +1 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.js +106 -0
- package/dist/react/features/chat-pane/components/AgentRuntimePicker.js.map +1 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts +10 -0
- package/dist/react/features/chat-pane/components/ChatPane.d.ts.map +1 -0
- package/dist/react/features/chat-pane/components/ChatPane.js +169 -0
- package/dist/react/features/chat-pane/components/ChatPane.js.map +1 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts +21 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.d.ts.map +1 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js +213 -0
- package/dist/react/features/chat-pane/create-daemon-attachment-uploader.js.map +1 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts +70 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.d.ts.map +1 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js +76 -0
- package/dist/react/features/chat-pane/create-mcp-ui-tool-caller.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js +258 -0
- package/dist/react/features/chat-pane/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts +66 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js +224 -0
- package/dist/react/features/chat-pane/hooks/useChatPane.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js +252 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts +16 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js +59 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneControlsHeight.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js +74 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js +88 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
- package/dist/react/features/chat-pane/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/index.d.ts +12 -0
- package/dist/react/features/chat-pane/index.d.ts.map +1 -0
- package/dist/react/features/chat-pane/index.js +11 -0
- package/dist/react/features/chat-pane/index.js.map +1 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts +12 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js +102 -0
- package/dist/react/features/chat-pane/react/components/AgentRuntimePicker.js.map +1 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.d.ts +10 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.js +137 -0
- package/dist/react/features/chat-pane/react/components/ChatPane.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts +133 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js +258 -0
- package/dist/react/features/chat-pane/react/hooks/useAgentRuntimePicker.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts +66 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js +223 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPane.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js +252 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneAgentControl.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts +26 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js +60 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneFileDrop.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts +25 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js +83 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneRuntimeInventory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts +38 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js +184 -0
- package/dist/react/features/chat-pane/react/hooks/useChatPaneWorkingDirectory.hooks.js.map +1 -0
- package/dist/react/features/chat-pane/react/styles.d.ts +2 -0
- package/dist/react/features/chat-pane/react/styles.d.ts.map +1 -0
- package/dist/react/features/chat-pane/react/styles.js +863 -0
- package/dist/react/features/chat-pane/react/styles.js.map +1 -0
- package/dist/react/features/chat-pane/rules.d.ts +31 -0
- package/dist/react/features/chat-pane/rules.d.ts.map +1 -0
- package/dist/react/features/chat-pane/rules.js +81 -0
- package/dist/react/features/chat-pane/rules.js.map +1 -0
- package/dist/react/features/chat-pane/styles.d.ts +2 -0
- package/dist/react/features/chat-pane/styles.d.ts.map +1 -0
- package/dist/react/features/chat-pane/styles.js +1327 -0
- package/dist/react/features/chat-pane/styles.js.map +1 -0
- package/dist/react/features/chat-pane/types.d.ts +248 -0
- package/dist/react/features/chat-pane/types.d.ts.map +1 -0
- package/dist/react/features/chat-pane/types.js +2 -0
- package/dist/react/features/chat-pane/types.js.map +1 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts +7 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.d.ts.map +1 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.js +20 -0
- package/dist/react/features/model-picker/components/CredentialStatusBadge.js.map +1 -0
- package/dist/react/features/model-picker/components/ModelPicker.d.ts +9 -0
- package/dist/react/features/model-picker/components/ModelPicker.d.ts.map +1 -0
- package/dist/react/features/model-picker/components/ModelPicker.js +34 -0
- package/dist/react/features/model-picker/components/ModelPicker.js.map +1 -0
- package/dist/react/features/model-picker/constants.d.ts +6 -0
- package/dist/react/features/model-picker/constants.d.ts.map +1 -0
- package/dist/react/features/model-picker/constants.js +9 -0
- package/dist/react/features/model-picker/constants.js.map +1 -0
- package/dist/react/features/model-picker/dependencies.d.ts +11 -0
- package/dist/react/features/model-picker/dependencies.d.ts.map +1 -0
- package/dist/react/features/model-picker/dependencies.js +10 -0
- package/dist/react/features/model-picker/dependencies.js.map +1 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts +27 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.d.ts.map +1 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js +62 -0
- package/dist/react/features/model-picker/hooks/useModelPicker.hooks.js.map +1 -0
- package/dist/react/features/model-picker/index.d.ts +32 -0
- package/dist/react/features/model-picker/index.d.ts.map +1 -0
- package/dist/react/features/model-picker/index.js +29 -0
- package/dist/react/features/model-picker/index.js.map +1 -0
- package/dist/react/features/model-picker/ports.d.ts +11 -0
- package/dist/react/features/model-picker/ports.d.ts.map +1 -0
- package/dist/react/features/model-picker/ports.js +2 -0
- package/dist/react/features/model-picker/ports.js.map +1 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts +7 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js +20 -0
- package/dist/react/features/model-picker/react/components/CredentialStatusBadge.js.map +1 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.d.ts +9 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.js +34 -0
- package/dist/react/features/model-picker/react/components/ModelPicker.js.map +1 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts +27 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.d.ts.map +1 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js +62 -0
- package/dist/react/features/model-picker/react/hooks/useModelPicker.hooks.js.map +1 -0
- package/dist/react/features/model-picker/rules.d.ts +26 -0
- package/dist/react/features/model-picker/rules.d.ts.map +1 -0
- package/dist/react/features/model-picker/rules.js +84 -0
- package/dist/react/features/model-picker/rules.js.map +1 -0
- package/dist/react/features/model-picker/types.d.ts +38 -0
- package/dist/react/features/model-picker/types.d.ts.map +1 -0
- package/dist/react/features/model-picker/types.js +2 -0
- package/dist/react/features/model-picker/types.js.map +1 -0
- package/dist/react/hooks/composer-draft-cache.d.ts +65 -0
- package/dist/react/hooks/composer-draft-cache.d.ts.map +1 -0
- package/dist/react/hooks/composer-draft-cache.js +89 -0
- package/dist/react/hooks/composer-draft-cache.js.map +1 -0
- package/dist/react/hooks/context.d.ts +18 -0
- package/dist/react/hooks/context.d.ts.map +1 -0
- package/dist/react/hooks/context.js +60 -0
- package/dist/react/hooks/context.js.map +1 -0
- package/dist/react/hooks/testing/fake-transport.d.ts +34 -0
- package/dist/react/hooks/testing/fake-transport.d.ts.map +1 -0
- package/dist/react/hooks/testing/fake-transport.js +46 -0
- package/dist/react/hooks/testing/fake-transport.js.map +1 -0
- package/dist/react/hooks/useArtifactStream.d.ts +18 -0
- package/dist/react/hooks/useArtifactStream.d.ts.map +1 -0
- package/dist/react/hooks/useArtifactStream.js +55 -0
- package/dist/react/hooks/useArtifactStream.js.map +1 -0
- package/dist/react/hooks/useChatFabDrag.d.ts +25 -0
- package/dist/react/hooks/useChatFabDrag.d.ts.map +1 -0
- package/dist/react/hooks/useChatFabDrag.js +88 -0
- package/dist/react/hooks/useChatFabDrag.js.map +1 -0
- package/dist/react/hooks/useComposer.d.ts +48 -0
- package/dist/react/hooks/useComposer.d.ts.map +1 -0
- package/dist/react/hooks/useComposer.js +121 -0
- package/dist/react/hooks/useComposer.js.map +1 -0
- package/dist/react/hooks/useConversation.d.ts +34 -0
- package/dist/react/hooks/useConversation.d.ts.map +1 -0
- package/dist/react/hooks/useConversation.js +163 -0
- package/dist/react/hooks/useConversation.js.map +1 -0
- package/dist/react/hooks/useCopyToClipboard.d.ts +14 -0
- package/dist/react/hooks/useCopyToClipboard.d.ts.map +1 -0
- package/dist/react/hooks/useCopyToClipboard.js +98 -0
- package/dist/react/hooks/useCopyToClipboard.js.map +1 -0
- package/dist/react/hooks/useExtEventGroups.d.ts +7 -0
- package/dist/react/hooks/useExtEventGroups.d.ts.map +1 -0
- package/dist/react/hooks/useExtEventGroups.js +32 -0
- package/dist/react/hooks/useExtEventGroups.js.map +1 -0
- package/dist/react/hooks/useLatestOperation.d.ts +31 -0
- package/dist/react/hooks/useLatestOperation.d.ts.map +1 -0
- package/dist/react/hooks/useLatestOperation.js +74 -0
- package/dist/react/hooks/useLatestOperation.js.map +1 -0
- package/dist/react/hooks/usePinnedTodos.d.ts +15 -0
- package/dist/react/hooks/usePinnedTodos.d.ts.map +1 -0
- package/dist/react/hooks/usePinnedTodos.js +43 -0
- package/dist/react/hooks/usePinnedTodos.js.map +1 -0
- package/dist/react/hooks/useQuestionForms.d.ts +28 -0
- package/dist/react/hooks/useQuestionForms.d.ts.map +1 -0
- package/dist/react/hooks/useQuestionForms.js +113 -0
- package/dist/react/hooks/useQuestionForms.js.map +1 -0
- package/dist/react/hooks/useRunStream.d.ts +27 -0
- package/dist/react/hooks/useRunStream.d.ts.map +1 -0
- package/dist/react/hooks/useRunStream.js +180 -0
- package/dist/react/hooks/useRunStream.js.map +1 -0
- package/dist/react/hooks/useToolTimeline.d.ts +33 -0
- package/dist/react/hooks/useToolTimeline.d.ts.map +1 -0
- package/dist/react/hooks/useToolTimeline.js +47 -0
- package/dist/react/hooks/useToolTimeline.js.map +1 -0
- package/dist/react/index.d.ts +158 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +118 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/message-blocks.d.ts +86 -0
- package/dist/react/message-blocks.d.ts.map +1 -0
- package/dist/react/message-blocks.js +78 -0
- package/dist/react/message-blocks.js.map +1 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts +9 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.d.ts.map +1 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js +29 -0
- package/dist/react/poc-mcp-ui-official/PocMcpUiCard.js.map +1 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts +30 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.d.ts.map +1 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.js +44 -0
- package/dist/react/poc-mcp-ui-official/create-poc-resource.js.map +1 -0
- package/dist/react/slots.d.ts +215 -0
- package/dist/react/slots.d.ts.map +1 -0
- package/dist/react/slots.js +2 -0
- package/dist/react/slots.js.map +1 -0
- package/dist/react/styles/reference.css +298 -0
- package/dist/react/tool-renderer-registry.d.ts +41 -0
- package/dist/react/tool-renderer-registry.d.ts.map +1 -0
- package/dist/react/tool-renderer-registry.js +22 -0
- package/dist/react/tool-renderer-registry.js.map +1 -0
- package/dist/react/util/defined-props.d.ts +31 -0
- package/dist/react/util/defined-props.d.ts.map +1 -0
- package/dist/react/util/defined-props.js +28 -0
- package/dist/react/util/defined-props.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC;;;;;;GAMG;AACH,cAAc,oBAAoB,CAAC;AACnC;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@jini-ai/chat/core` — framework-free chat vocabulary + pure parsers.
|
|
3
|
+
*
|
|
4
|
+
* Zero React, zero DOM/browser globals, zero Node built-ins, zero imports
|
|
5
|
+
* from any product package's scope. See ADS-memory/reports/jini-port/extraction-plan.md
|
|
6
|
+
* §12 C2/C3 and ADS-memory/reports/jini-port/recon/r4b-webui-design.md §1 for the design
|
|
7
|
+
* this package targets, and source-map.md for exact provenance.
|
|
8
|
+
*
|
|
9
|
+
* Was `@jini-ai/chat-core` (its own top-level package, one entry point) through npm 0.1.2 —
|
|
10
|
+
* consolidated 2026-08-03 into `@jini-ai/chat`'s `./core` subpath alongside `./react` (formerly
|
|
11
|
+
* `@jini-ai/ui`'s `./chat` export), following `@jini-ai/admin`'s umbrella-with-subpaths precedent.
|
|
12
|
+
* `@jini-ai/chat-core` is retired, not deprecated-and-kept — its published npm versions
|
|
13
|
+
* (0.1.0–0.1.2) go end-of-life as-is; `@jini-ai/chat` supersedes it.
|
|
14
|
+
*/
|
|
15
|
+
export * from './events.js';
|
|
16
|
+
export * from './messages.js';
|
|
17
|
+
export * from './partial-json.js';
|
|
18
|
+
export * from './tool-events.js';
|
|
19
|
+
export * from './transport.js';
|
|
20
|
+
export * from './tools.js';
|
|
21
|
+
export * from './todos.js';
|
|
22
|
+
export * from './question-form.js';
|
|
23
|
+
export * from './util/index.js';
|
|
24
|
+
export * from './transcript.js';
|
|
25
|
+
/**
|
|
26
|
+
* The chat pane's own capability manifest (`CHAT_CAPABILITIES`). The framework-free agent-control
|
|
27
|
+
* vocabulary this used to sit alongside — `CapabilityDef`, `PAGE_CAPABILITIES`, the
|
|
28
|
+
* `data-agent-*` convention, the policy gate, the protocol projections — moved to `@jini-ai/agentic`
|
|
29
|
+
* on 2026-07-26; import it directly rather than through this package. See
|
|
30
|
+
* `packages/agentic/source-map.md` and this package's own source-map.md for the extraction.
|
|
31
|
+
*/
|
|
32
|
+
export * from './agentic/index.js';
|
|
33
|
+
/**
|
|
34
|
+
* Durable chat history — the storage-neutral `ChatHistoryStore` port and the local title
|
|
35
|
+
* heuristic. Types and pure functions only, so this package stays framework-free and
|
|
36
|
+
* `runtime: universal`; the SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history`
|
|
37
|
+
* module, and a host binds it to its own authentication.
|
|
38
|
+
*/
|
|
39
|
+
export * from './persistence/index.js';
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC;;;;;;GAMG;AACH,cAAc,oBAAoB,CAAC;AACnC;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { AgentEvent } from './events.js';
|
|
2
|
+
/** Who authored a `ChatMessage`. */
|
|
3
|
+
export type ChatRole = 'user' | 'assistant';
|
|
4
|
+
/**
|
|
5
|
+
* Terminal/non-terminal lifecycle of the run backing an assistant message.
|
|
6
|
+
*
|
|
7
|
+
* Named `ChatRunStatus`, not `RunStatus` (renamed 2026-07-29): `@jini-ai/protocol` owns
|
|
8
|
+
* `RunStatus` for a different shape at a different layer — a richer `{ id, state, ... }` record.
|
|
9
|
+
* This is the flat string union a chat message stamps on itself. While both were called
|
|
10
|
+
* `RunStatus`, every consumer importing both packages had to alias one on import, and nothing
|
|
11
|
+
* stopped the two from being confused at a glance. See source-map.md.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CHAT_RUN_STATUSES: readonly ["queued", "running", "succeeded", "failed", "canceled"];
|
|
14
|
+
export type ChatRunStatus = (typeof CHAT_RUN_STATUSES)[number];
|
|
15
|
+
/** `true` once a run has reached a terminal status (no further events will arrive). */
|
|
16
|
+
export declare function isTerminalRunStatus(status: ChatRunStatus | undefined): boolean;
|
|
17
|
+
/** A file or image a user turn carries alongside its text. */
|
|
18
|
+
export interface ChatAttachment {
|
|
19
|
+
path: string;
|
|
20
|
+
name: string;
|
|
21
|
+
kind: 'image' | 'file';
|
|
22
|
+
size?: number;
|
|
23
|
+
/** User-visible attachment order for this turn; older items may omit it. */
|
|
24
|
+
order?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A single turn in a conversation. This is the generic subset of OD's
|
|
28
|
+
* `ChatMessage` (`packages/contracts/src/api/chat.ts`): product-shaped
|
|
29
|
+
* fields (`sessionMode`, `runContext`, `appliedPluginSnapshot`,
|
|
30
|
+
* `producedFiles`, `commentAttachments`, `feedback`, ...) are dropped — a
|
|
31
|
+
* host layers those on top via its own message extension, not this type.
|
|
32
|
+
*/
|
|
33
|
+
export interface ChatMessage {
|
|
34
|
+
id: string;
|
|
35
|
+
role: ChatRole;
|
|
36
|
+
content: string;
|
|
37
|
+
agentId?: string;
|
|
38
|
+
agentName?: string;
|
|
39
|
+
events?: AgentEvent[];
|
|
40
|
+
createdAt?: number;
|
|
41
|
+
runId?: string;
|
|
42
|
+
runStatus?: ChatRunStatus;
|
|
43
|
+
/**
|
|
44
|
+
* True when this message's failed run can be recovered by resuming the
|
|
45
|
+
* agent's existing session rather than only restarting from scratch.
|
|
46
|
+
*/
|
|
47
|
+
resumable?: boolean;
|
|
48
|
+
lastRunEventId?: string;
|
|
49
|
+
startedAt?: number;
|
|
50
|
+
endedAt?: number;
|
|
51
|
+
attachments?: ChatAttachment[];
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oCAAoC;AACpC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5C;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,mEAAoE,CAAC;AACnG,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAI/D,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAE9E;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal/non-terminal lifecycle of the run backing an assistant message.
|
|
3
|
+
*
|
|
4
|
+
* Named `ChatRunStatus`, not `RunStatus` (renamed 2026-07-29): `@jini-ai/protocol` owns
|
|
5
|
+
* `RunStatus` for a different shape at a different layer — a richer `{ id, state, ... }` record.
|
|
6
|
+
* This is the flat string union a chat message stamps on itself. While both were called
|
|
7
|
+
* `RunStatus`, every consumer importing both packages had to alias one on import, and nothing
|
|
8
|
+
* stopped the two from being confused at a glance. See source-map.md.
|
|
9
|
+
*/
|
|
10
|
+
export const CHAT_RUN_STATUSES = ['queued', 'running', 'succeeded', 'failed', 'canceled'];
|
|
11
|
+
const TERMINAL_RUN_STATUSES = new Set(['succeeded', 'failed', 'canceled']);
|
|
12
|
+
/** `true` once a run has reached a terminal status (no further events will arrive). */
|
|
13
|
+
export function isTerminalRunStatus(status) {
|
|
14
|
+
return status !== undefined && TERMINAL_RUN_STATUSES.has(status);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/core/messages.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAGnG,MAAM,qBAAqB,GAA+B,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAEvG,uFAAuF;AACvF,MAAM,UAAU,mBAAmB,CAAC,MAAiC;IACnE,OAAO,MAAM,KAAK,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module partial-json
|
|
3
|
+
*
|
|
4
|
+
* Truncation-tolerant JSON parsing for streamed LLM output. A streaming
|
|
5
|
+
* `<question-form>` (or any other structured artifact) needs to render a
|
|
6
|
+
* JSON *prefix* that grows one token at a time, so callers rely on this
|
|
7
|
+
* repair pass instead of waiting for the closing brace.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately handles only the shapes a streaming model emits — balanced
|
|
10
|
+
* structure that simply hasn't finished — not arbitrary corruption. Callers
|
|
11
|
+
* should still keep their last good parsed result as a fallback.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Repair a truncated JSON prefix into the largest valid JSON text that can be
|
|
15
|
+
* parsed, by walking the buffer once to track string/escape state and the
|
|
16
|
+
* open-container stack, then closing whatever is still open.
|
|
17
|
+
*
|
|
18
|
+
* @param buf - A possibly-incomplete JSON text (a streamed prefix).
|
|
19
|
+
* @returns A best-effort syntactically-closed JSON text. Not guaranteed to
|
|
20
|
+
* parse (e.g. an empty buffer round-trips unchanged) — callers should still
|
|
21
|
+
* wrap consumption in `JSON.parse`/try-catch (see {@link parsePartialJson}).
|
|
22
|
+
* @complexity O(n) time / O(d) space in the input length `n` and max nesting
|
|
23
|
+
* depth `d` — one linear scan plus a bounded fixed-point cleanup loop over
|
|
24
|
+
* the (already shrinking) tail.
|
|
25
|
+
*/
|
|
26
|
+
export declare function repairJsonPrefix(buf: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Best-effort parse of a (possibly truncated) JSON prefix.
|
|
29
|
+
*
|
|
30
|
+
* @param buf - A possibly-incomplete JSON text.
|
|
31
|
+
* @returns The parsed value, or `null` on empty input or an unrecoverable
|
|
32
|
+
* parse failure — callers should fall back to their last good value.
|
|
33
|
+
* @complexity O(n) — dominated by {@link repairJsonPrefix}.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parsePartialJson(buf: string): unknown;
|
|
36
|
+
//# sourceMappingURL=partial-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial-json.d.ts","sourceRoot":"","sources":["../../src/core/partial-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQrD"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module partial-json
|
|
3
|
+
*
|
|
4
|
+
* Truncation-tolerant JSON parsing for streamed LLM output. A streaming
|
|
5
|
+
* `<question-form>` (or any other structured artifact) needs to render a
|
|
6
|
+
* JSON *prefix* that grows one token at a time, so callers rely on this
|
|
7
|
+
* repair pass instead of waiting for the closing brace.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately handles only the shapes a streaming model emits — balanced
|
|
10
|
+
* structure that simply hasn't finished — not arbitrary corruption. Callers
|
|
11
|
+
* should still keep their last good parsed result as a fallback.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Repair a truncated JSON prefix into the largest valid JSON text that can be
|
|
15
|
+
* parsed, by walking the buffer once to track string/escape state and the
|
|
16
|
+
* open-container stack, then closing whatever is still open.
|
|
17
|
+
*
|
|
18
|
+
* @param buf - A possibly-incomplete JSON text (a streamed prefix).
|
|
19
|
+
* @returns A best-effort syntactically-closed JSON text. Not guaranteed to
|
|
20
|
+
* parse (e.g. an empty buffer round-trips unchanged) — callers should still
|
|
21
|
+
* wrap consumption in `JSON.parse`/try-catch (see {@link parsePartialJson}).
|
|
22
|
+
* @complexity O(n) time / O(d) space in the input length `n` and max nesting
|
|
23
|
+
* depth `d` — one linear scan plus a bounded fixed-point cleanup loop over
|
|
24
|
+
* the (already shrinking) tail.
|
|
25
|
+
*/
|
|
26
|
+
export function repairJsonPrefix(buf) {
|
|
27
|
+
const stack = []; // closers owed, e.g. ['}', ']']
|
|
28
|
+
let inStr = false;
|
|
29
|
+
let esc = false;
|
|
30
|
+
for (let i = 0; i < buf.length; i++) {
|
|
31
|
+
const c = buf[i];
|
|
32
|
+
if (inStr) {
|
|
33
|
+
if (esc)
|
|
34
|
+
esc = false;
|
|
35
|
+
else if (c === '\\')
|
|
36
|
+
esc = true;
|
|
37
|
+
else if (c === '"')
|
|
38
|
+
inStr = false;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (c === '"')
|
|
42
|
+
inStr = true;
|
|
43
|
+
else if (c === '{')
|
|
44
|
+
stack.push('}');
|
|
45
|
+
else if (c === '[')
|
|
46
|
+
stack.push(']');
|
|
47
|
+
else if (c === '}' || c === ']')
|
|
48
|
+
stack.pop();
|
|
49
|
+
}
|
|
50
|
+
let out = buf;
|
|
51
|
+
// 1. Close a string cut off mid-value (or mid-key). First neutralize a
|
|
52
|
+
// dangling escape at the cut point, otherwise the closing quote would be
|
|
53
|
+
// swallowed (`...x\` + `"` → escaped quote) or a partial `\uXXXX` would
|
|
54
|
+
// be an invalid escape — either makes JSON.parse fail and collapses the
|
|
55
|
+
// live preview. Common in prompts that mention Windows paths, regexes,
|
|
56
|
+
// or escaped quotes.
|
|
57
|
+
if (inStr) {
|
|
58
|
+
out = out.replace(/\\u[0-9a-fA-F]{0,3}$/, ''); // incomplete \uXXXX
|
|
59
|
+
if (/(?:^|[^\\])(?:\\\\)*\\$/.test(out))
|
|
60
|
+
out = out.slice(0, -1); // lone trailing backslash
|
|
61
|
+
out += '"';
|
|
62
|
+
}
|
|
63
|
+
// 2. Trim trailing structural noise that can't be completed into a value:
|
|
64
|
+
// a dangling comma, a `"key":` with no value yet, and an unfinished
|
|
65
|
+
// *scalar* value cut mid-token (a partial `true`/`false`/`null`, or a
|
|
66
|
+
// number ending on `.`/`e`/sign). Leaving those makes `{… :f}` etc.
|
|
67
|
+
// unparseable, collapsing the live preview whenever a literal splits
|
|
68
|
+
// across deltas. Each trim leaves a `"key":` / `,` / `[` boundary that
|
|
69
|
+
// the next loop iteration cleans up. Complete literals (`true`, `12`,
|
|
70
|
+
// `1.5`, `1e3`) are not prefixes of these patterns, so they survive.
|
|
71
|
+
const valueStart = '([:[,]\\s*)';
|
|
72
|
+
let prev;
|
|
73
|
+
do {
|
|
74
|
+
prev = out;
|
|
75
|
+
out = out.replace(/[,\s]+$/, '');
|
|
76
|
+
out = out.replace(/"(?:[^"\\]|\\.)*"\s*:\s*$/, ''); // key + colon, no value
|
|
77
|
+
out = out.replace(new RegExp(`${valueStart}(?:tru|tr|t|fals|fal|fa|f|nul|nu|n)$`), '$1'); // partial bool/null
|
|
78
|
+
out = out.replace(new RegExp(`${valueStart}-?(?:\\d+\\.?\\d*|\\d*\\.\\d+)?[eE][+-]?$`), '$1'); // dangling exponent
|
|
79
|
+
out = out.replace(new RegExp(`${valueStart}-?\\d*\\.$`), '$1'); // number ending in '.'
|
|
80
|
+
out = out.replace(new RegExp(`${valueStart}-$`), '$1'); // lone minus
|
|
81
|
+
out = out.replace(/"(?:[^"\\]|\\.)*"\s*:\s*$/, ''); // key + colon exposed by the trims above
|
|
82
|
+
out = out.replace(/[,\s]+$/, '');
|
|
83
|
+
} while (out !== prev);
|
|
84
|
+
// A bare trailing key (string with no following colon) only happens when
|
|
85
|
+
// the *innermost* open container is an object. Drop it so we don't emit
|
|
86
|
+
// `{"hea"}` which is invalid (key without value).
|
|
87
|
+
if (stack[stack.length - 1] === '}' && /"(?:[^"\\]|\\.)*"\s*$/.test(out)) {
|
|
88
|
+
const trimmed = out.replace(/"(?:[^"\\]|\\.)*"\s*$/, '');
|
|
89
|
+
// Only drop it if what precedes is a container/comma boundary (i.e. the
|
|
90
|
+
// string really is a pending key, not a completed value like `:"x"`).
|
|
91
|
+
if (/[{,]\s*$/.test(trimmed)) {
|
|
92
|
+
out = trimmed.replace(/[,\s]+$/, '');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 3. Close every still-open container, innermost first.
|
|
96
|
+
for (let i = stack.length - 1; i >= 0; i--)
|
|
97
|
+
out += stack[i];
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Best-effort parse of a (possibly truncated) JSON prefix.
|
|
102
|
+
*
|
|
103
|
+
* @param buf - A possibly-incomplete JSON text.
|
|
104
|
+
* @returns The parsed value, or `null` on empty input or an unrecoverable
|
|
105
|
+
* parse failure — callers should fall back to their last good value.
|
|
106
|
+
* @complexity O(n) — dominated by {@link repairJsonPrefix}.
|
|
107
|
+
*/
|
|
108
|
+
export function parsePartialJson(buf) {
|
|
109
|
+
const trimmed = buf.trim();
|
|
110
|
+
if (!trimmed)
|
|
111
|
+
return null;
|
|
112
|
+
try {
|
|
113
|
+
return JSON.parse(repairJsonPrefix(trimmed));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=partial-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial-json.js","sourceRoot":"","sources":["../../src/core/partial-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAa,EAAE,CAAC,CAAC,gCAAgC;IAC5D,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG;gBAAE,GAAG,GAAG,KAAK,CAAC;iBAChB,IAAI,CAAC,KAAK,IAAI;gBAAE,GAAG,GAAG,IAAI,CAAC;iBAC3B,IAAI,CAAC,KAAK,GAAG;gBAAE,KAAK,GAAG,KAAK,CAAC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,GAAG,IAAI,CAAC;aACvB,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAC/B,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,KAAK,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,uEAAuE;IACvE,4EAA4E;IAC5E,2EAA2E;IAC3E,2EAA2E;IAC3E,0EAA0E;IAC1E,wBAAwB;IACxB,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;QACnE,IAAI,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B;QAC3F,GAAG,IAAI,GAAG,CAAC;IACb,CAAC;IACD,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,uEAAuE;IACvE,wEAAwE;IACxE,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,UAAU,GAAG,aAAa,CAAC;IACjC,IAAI,IAAY,CAAC;IACjB,GAAG,CAAC;QACF,IAAI,GAAG,GAAG,CAAC;QACX,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACjC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB;QAC5E,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,sCAAsC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB;QAC9G,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,2CAA2C,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB;QACnH,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,uBAAuB;QACvF,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa;QACrE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC,CAAC,yCAAyC;QAC7F,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACnC,CAAC,QAAQ,GAAG,KAAK,IAAI,EAAE;IACvB,yEAAyE;IACzE,wEAAwE;IACxE,kDAAkD;IAClD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACzD,wEAAwE;QACxE,sEAAsE;QACtE,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,wDAAwD;IACxD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5D,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module persistence
|
|
3
|
+
*
|
|
4
|
+
* Durable chat history: the storage-neutral port plus the local title heuristic. No driver, no
|
|
5
|
+
* DDL, no I/O — a SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history` module, and
|
|
6
|
+
* a host binds it to its own auth. See `./ports.ts` for why the owner scope is bound into the
|
|
7
|
+
* store rather than passed per call.
|
|
8
|
+
*/
|
|
9
|
+
export * from './ports.js';
|
|
10
|
+
export * from './title.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module persistence
|
|
3
|
+
*
|
|
4
|
+
* Durable chat history: the storage-neutral port plus the local title heuristic. No driver, no
|
|
5
|
+
* DDL, no I/O — a SQLite implementation lives in `@jini-ai/sqlite`'s `chat-history` module, and
|
|
6
|
+
* a host binds it to its own auth. See `./ports.ts` for why the owner scope is bound into the
|
|
7
|
+
* store rather than passed per call.
|
|
8
|
+
*/
|
|
9
|
+
export * from './ports.js';
|
|
10
|
+
export * from './title.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/persistence/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module persistence/ports
|
|
3
|
+
*
|
|
4
|
+
* The storage-neutral contract for durable chat history: conversations and their messages,
|
|
5
|
+
* scoped to an owner. Types and signatures only — this module imports no driver, opens no
|
|
6
|
+
* file, and issues no DDL, so it stays inside `chat-core`'s `runtime: universal` promise.
|
|
7
|
+
*
|
|
8
|
+
* Why here and not in `@jini-ai/agentic`: `chat-core` already depends on `agentic`, so a port
|
|
9
|
+
* living in `agentic` could not import {@link ChatMessage} — the type it exists to persist —
|
|
10
|
+
* without inverting that edge. It would have to redefine the message shape (two sources of
|
|
11
|
+
* truth) or be generic over an opaque type (a persistence abstraction naming nothing).
|
|
12
|
+
*
|
|
13
|
+
* Why the owner scope is baked into the port rather than passed per call: every read must be
|
|
14
|
+
* `WHERE scope = ? AND owner = ? AND id = ?`, never `WHERE id = ?`. A port whose methods take
|
|
15
|
+
* a bare id invites exactly one bug — a handler that forgets the predicate — and that bug is
|
|
16
|
+
* an omission, so review does not reliably catch it. {@link ChatHistoryStore} is obtained
|
|
17
|
+
* already-bound to a {@link ChatOwnerScope}; there is no method on it that can read across
|
|
18
|
+
* owners. Hosts bind the scope from their own auth, which is the one part of this that cannot
|
|
19
|
+
* be reused.
|
|
20
|
+
*/
|
|
21
|
+
import type { ChatMessage } from '../messages.js';
|
|
22
|
+
/**
|
|
23
|
+
* Which kind of principal owns a conversation.
|
|
24
|
+
*
|
|
25
|
+
* `user` is an authenticated account; `guest` is an anonymous visitor identified only by an
|
|
26
|
+
* opaque bearer token. They are separated rather than collapsed into one `ownerId` because the
|
|
27
|
+
* retention and disclosure rules differ: guest history expires, user history does not, and a
|
|
28
|
+
* guest's identifier is a credential that must be stored hashed.
|
|
29
|
+
*/
|
|
30
|
+
export type ChatOwnerKind = 'user' | 'guest';
|
|
31
|
+
/**
|
|
32
|
+
* The isolation predicate, resolved by the host from its own authentication, and bound into a
|
|
33
|
+
* store before any query runs.
|
|
34
|
+
*
|
|
35
|
+
* `scopeId` is the host's partition key — a workspace, a tenant, a project, whatever that host
|
|
36
|
+
* partitions by. This package does not interpret it; it only guarantees every statement filters
|
|
37
|
+
* on it.
|
|
38
|
+
*
|
|
39
|
+
* `ownerId` for a `guest` MUST already be hashed by the host. This package never sees, stores,
|
|
40
|
+
* or logs a raw bearer token, and cannot verify that a caller honored this — it is stated here
|
|
41
|
+
* because the constraint is real and the type system cannot express it.
|
|
42
|
+
*/
|
|
43
|
+
export interface ChatOwnerScope {
|
|
44
|
+
readonly scopeId: string;
|
|
45
|
+
readonly ownerKind: ChatOwnerKind;
|
|
46
|
+
readonly ownerId: string;
|
|
47
|
+
}
|
|
48
|
+
/** Where a conversation's current title came from — see {@link ChatHistoryStore.rename}. */
|
|
49
|
+
export type ChatTitleSource = 'fallback' | 'generated' | 'manual';
|
|
50
|
+
/**
|
|
51
|
+
* A conversation as the list UI needs it: enough to render a row without loading any messages.
|
|
52
|
+
*
|
|
53
|
+
* `messageCount` is computed by the adapter in the same round-trip as the list itself, so a
|
|
54
|
+
* list of N conversations costs one query rather than N+1.
|
|
55
|
+
*/
|
|
56
|
+
export interface ChatConversation {
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly title: string | null;
|
|
59
|
+
readonly titleSource: ChatTitleSource;
|
|
60
|
+
readonly messageCount: number;
|
|
61
|
+
readonly createdAt: number;
|
|
62
|
+
readonly updatedAt: number;
|
|
63
|
+
/** Absent means no expiry — the row is retained until explicitly deleted. */
|
|
64
|
+
readonly expiresAt?: number;
|
|
65
|
+
}
|
|
66
|
+
/** Everything a host may specify when starting a conversation. */
|
|
67
|
+
export interface CreateChatConversationInput {
|
|
68
|
+
readonly id: string;
|
|
69
|
+
readonly title?: string | null;
|
|
70
|
+
readonly titleSource?: ChatTitleSource;
|
|
71
|
+
/** Epoch ms. Omit for history that never expires. */
|
|
72
|
+
readonly expiresAt?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Durable chat history for exactly one {@link ChatOwnerScope}.
|
|
76
|
+
*
|
|
77
|
+
* Every method is already scoped. `get(id)` for an id belonging to another owner resolves to
|
|
78
|
+
* `null` rather than throwing — a caller must not be able to distinguish "does not exist" from
|
|
79
|
+
* "exists but is not yours", since that distinction is itself an enumeration oracle.
|
|
80
|
+
*/
|
|
81
|
+
export interface ChatHistoryStore {
|
|
82
|
+
/** Most-recently-updated first. */
|
|
83
|
+
list(): Promise<ChatConversation[]>;
|
|
84
|
+
/** `null` when the id does not exist *or* is not owned by this scope. */
|
|
85
|
+
get(id: string): Promise<ChatConversation | null>;
|
|
86
|
+
create(input: CreateChatConversationInput): Promise<ChatConversation>;
|
|
87
|
+
/**
|
|
88
|
+
* Sets the title and stamps `titleSource`. A `manual` title is never overwritten by a
|
|
89
|
+
* `generated` one — that rule lives in the adapter so no host can forget it, and it is the
|
|
90
|
+
* reason `titleSource` is a column rather than a UI concern.
|
|
91
|
+
*/
|
|
92
|
+
rename(id: string, title: string, source?: ChatTitleSource): Promise<ChatConversation | null>;
|
|
93
|
+
/** Bumps `updatedAt`, optionally extending expiry for a still-active guest session. */
|
|
94
|
+
touch(id: string, options?: {
|
|
95
|
+
readonly expiresAt?: number;
|
|
96
|
+
}): Promise<void>;
|
|
97
|
+
/** Cascades to the conversation's messages. No-op when the id is not owned by this scope. */
|
|
98
|
+
delete(id: string): Promise<void>;
|
|
99
|
+
/** Ordered by position. Empty when the id is not owned by this scope. */
|
|
100
|
+
messages(conversationId: string): Promise<ChatMessage[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Inserts or updates one message, assigning the next position on insert.
|
|
103
|
+
*
|
|
104
|
+
* `null` when the conversation is not owned by this scope — so a mis-scoped write is a
|
|
105
|
+
* no-op rather than a cross-owner insert.
|
|
106
|
+
*/
|
|
107
|
+
appendMessage(conversationId: string, message: ChatMessage): Promise<ChatMessage | null>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Retention. Deliberately NOT on {@link ChatHistoryStore}: a sweep runs across every owner, so
|
|
111
|
+
* putting it on a per-owner store would require an unscoped store to exist, which is the exact
|
|
112
|
+
* escape hatch this design removes.
|
|
113
|
+
*/
|
|
114
|
+
export interface ChatHistoryMaintenance {
|
|
115
|
+
/**
|
|
116
|
+
* Hard-deletes conversations whose `expiresAt` is at or before `now`, cascading to messages.
|
|
117
|
+
*
|
|
118
|
+
* `limit` bounds one call so a large backlog is drained in chunks rather than held in a
|
|
119
|
+
* single long write transaction — an unbounded `DELETE` is what starves concurrent inserts.
|
|
120
|
+
* Returns the number of conversations deleted, so a caller can loop until it reports 0.
|
|
121
|
+
*/
|
|
122
|
+
sweepExpired(now: number, limit?: number): Promise<number>;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,kEAAkE;AAClE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC;IACvC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACpC,yEAAyE;IACzE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9F,uFAAuF;IACvF,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,6FAA6F;IAC7F,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD;;;;;OAKG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC1F;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/core/persistence/ports.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module persistence/title
|
|
3
|
+
*
|
|
4
|
+
* Derives a conversation's working title from its first user message, synchronously and with no
|
|
5
|
+
* model call.
|
|
6
|
+
*
|
|
7
|
+
* The point of doing this locally is latency and cost: a conversation needs a name the instant
|
|
8
|
+
* it appears in a list, and for an anonymous-visitor surface a per-conversation LLM call to name
|
|
9
|
+
* a chat is a real cost against a session that may be one message long. A host that wants a
|
|
10
|
+
* better title asks its agent for one later and calls `rename(id, title, 'generated')`; the
|
|
11
|
+
* store refuses to overwrite a `manual` title, so a user's own rename always wins.
|
|
12
|
+
*
|
|
13
|
+
* Ported from Open Design's `summarizeProjectNameFromPrompt` (`apps/web/src/utils/projectName.ts`),
|
|
14
|
+
* which this generalizes from project names to conversation titles. Its behaviour is preserved
|
|
15
|
+
* deliberately — including the CJK path, which is not decoration: the filler and punctuation
|
|
16
|
+
* rules for Chinese prompts differ enough from the Latin ones that a shared code path produced
|
|
17
|
+
* visibly worse titles in both.
|
|
18
|
+
*
|
|
19
|
+
* Two intentional divergences from the original, both fixing output the original gets wrong; each
|
|
20
|
+
* is documented at its own declaration below:
|
|
21
|
+
* 1. `LEADING_LATIN_FILLER` requires the separator inside the article group. The original's form
|
|
22
|
+
* let a bare `a` eat the first letter of the next word ("update app.tsx" → "Pp Tsx").
|
|
23
|
+
* 2. `LATIN_NEVER_TRAILING` trims function words off the end. The original's word cap lands
|
|
24
|
+
* mid-clause on question-shaped prompts and strands them ("...Posts Do I").
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Returns a short display title for a conversation, or `''` when the prompt yields nothing
|
|
28
|
+
* usable (a bare URL, a lone code fence, pure punctuation). Callers should treat `''` as "leave
|
|
29
|
+
* the conversation untitled" rather than substituting the raw prompt — a list row showing 400
|
|
30
|
+
* characters of pasted code is worse than one showing "Untitled".
|
|
31
|
+
*
|
|
32
|
+
* @complexity O(n) in prompt length; no allocation beyond the intermediate strings.
|
|
33
|
+
*/
|
|
34
|
+
export declare function deriveConversationTitle(prompt: string): string;
|
|
35
|
+
//# sourceMappingURL=title.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../../src/core/persistence/title.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAuGH;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAS9D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module persistence/title
|
|
3
|
+
*
|
|
4
|
+
* Derives a conversation's working title from its first user message, synchronously and with no
|
|
5
|
+
* model call.
|
|
6
|
+
*
|
|
7
|
+
* The point of doing this locally is latency and cost: a conversation needs a name the instant
|
|
8
|
+
* it appears in a list, and for an anonymous-visitor surface a per-conversation LLM call to name
|
|
9
|
+
* a chat is a real cost against a session that may be one message long. A host that wants a
|
|
10
|
+
* better title asks its agent for one later and calls `rename(id, title, 'generated')`; the
|
|
11
|
+
* store refuses to overwrite a `manual` title, so a user's own rename always wins.
|
|
12
|
+
*
|
|
13
|
+
* Ported from Open Design's `summarizeProjectNameFromPrompt` (`apps/web/src/utils/projectName.ts`),
|
|
14
|
+
* which this generalizes from project names to conversation titles. Its behaviour is preserved
|
|
15
|
+
* deliberately — including the CJK path, which is not decoration: the filler and punctuation
|
|
16
|
+
* rules for Chinese prompts differ enough from the Latin ones that a shared code path produced
|
|
17
|
+
* visibly worse titles in both.
|
|
18
|
+
*
|
|
19
|
+
* Two intentional divergences from the original, both fixing output the original gets wrong; each
|
|
20
|
+
* is documented at its own declaration below:
|
|
21
|
+
* 1. `LEADING_LATIN_FILLER` requires the separator inside the article group. The original's form
|
|
22
|
+
* let a bare `a` eat the first letter of the next word ("update app.tsx" → "Pp Tsx").
|
|
23
|
+
* 2. `LATIN_NEVER_TRAILING` trims function words off the end. The original's word cap lands
|
|
24
|
+
* mid-clause on question-shaped prompts and strands them ("...Posts Do I").
|
|
25
|
+
*/
|
|
26
|
+
const MAX_LATIN_WORDS = 6;
|
|
27
|
+
const MAX_CJK_LENGTH = 18;
|
|
28
|
+
/**
|
|
29
|
+
* Hard character ceiling, because a word cap is not a length cap.
|
|
30
|
+
*
|
|
31
|
+
* Six "words" says nothing about their size: a pasted base64 blob or minified bundle is a single
|
|
32
|
+
* enormous token, so it survived the word cap intact and became the title verbatim. That title is
|
|
33
|
+
* then stored, listed, and re-rendered on every conversation-list read — megabytes of it. Applied to
|
|
34
|
+
* the finished title so both the Latin and CJK paths are covered.
|
|
35
|
+
*/
|
|
36
|
+
const MAX_TITLE_CHARS = 80;
|
|
37
|
+
const CJK_PATTERN = /[㐀-鿿]/;
|
|
38
|
+
/**
|
|
39
|
+
* Leading politeness/imperative filler — "can you build a dashboard" is a dashboard.
|
|
40
|
+
*
|
|
41
|
+
* The trailing article group requires `\s+` *inside* it rather than the original's
|
|
42
|
+
* `(an|a|the|…)?\s*`. That form is subtly wrong: with the whitespace outside the optional group,
|
|
43
|
+
* the bare `a` alternative happily matches the first letter of the following word, so
|
|
44
|
+
* "update app.tsx" became "Pp Tsx" and "build analytics" became "Nalytics". Any word starting
|
|
45
|
+
* with `a` after a verb silently lost its first character. Requiring the separator as part of the
|
|
46
|
+
* article makes an article an article rather than a prefix.
|
|
47
|
+
*/
|
|
48
|
+
const LEADING_LATIN_FILLER = /^(please\s+)?(can\s+you\s+|could\s+you\s+|help\s+me\s+|i\s+want\s+to\s+|i\s+need\s+to\s+)?(create|build|make|design|implement|add|fix|update|improve|optimize|generate|write|search|find|show|list|turn)\s+((this|that)\s+into\s+)?((an|a|the|this|that|my|me)\s+)?/i;
|
|
49
|
+
const LEADING_CJK_FILLER = [
|
|
50
|
+
/^先?(帮我|帮忙|麻烦|请|可以|能不能|能否|给我|我想要|我要)/,
|
|
51
|
+
/^(先)?(实现|做|做一下|创建|生成|设计|开发|新增|添加|优化|修复|改|更改|调整)(一下|一个|一版|下)?/,
|
|
52
|
+
/^(一个|一份|这个|那个)/,
|
|
53
|
+
];
|
|
54
|
+
const LATIN_STOP_WORDS = new Set([
|
|
55
|
+
'a', 'an', 'and', 'for', 'in', 'of', 'on', 'please', 'the', 'to', 'with', 'my',
|
|
56
|
+
]);
|
|
57
|
+
/**
|
|
58
|
+
* Function words that are fine *inside* a title but never acceptable as its last word.
|
|
59
|
+
*
|
|
60
|
+
* These cannot go in `LATIN_STOP_WORDS`, because removing them everywhere mangles real titles —
|
|
61
|
+
* "how many posts do I have" would lose the "how many" that makes it a question, and a prompt like
|
|
62
|
+
* "make it work" would reduce to "Work". The problem is specifically the word-cap boundary: a
|
|
63
|
+
* question-shaped prompt reliably spends its six words before reaching the noun, so the title got
|
|
64
|
+
* cut mid-clause. Observed live: "how many published posts do I have?" produced
|
|
65
|
+
* "How Many Published Posts Do I" — a dangling auxiliary plus a stranded pronoun, which in a narrow
|
|
66
|
+
* dock also wrapped to leave a lone "I" on its own line.
|
|
67
|
+
*
|
|
68
|
+
* Trimming only the tail is what makes this safe: it can never shorten a title that already ended
|
|
69
|
+
* on a content word, so no existing good title changes.
|
|
70
|
+
*/
|
|
71
|
+
const LATIN_NEVER_TRAILING = new Set([
|
|
72
|
+
'do', 'does', 'did', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
73
|
+
'have', 'has', 'had', 'can', 'could', 'should', 'would', 'will', 'shall', 'may', 'might', 'must',
|
|
74
|
+
'i', 'me', 'you', 'we', 'us', 'it', 'they', 'them', 'he', 'she',
|
|
75
|
+
'that', 'this', 'these', 'those', 'but', 'or', 'if', 'then', 'than', 'as', 'at', 'by',
|
|
76
|
+
'from', 'into', 'about', 'so', 'just', 'also', 'too', 'up', 'out',
|
|
77
|
+
]);
|
|
78
|
+
/**
|
|
79
|
+
* Strips the parts of a prompt that are never a good title: fenced and inline code, URLs, and
|
|
80
|
+
* `@handle`/`#tag` tokens. Each of these is high-entropy and low-meaning in a six-word summary.
|
|
81
|
+
*/
|
|
82
|
+
function cleanPrompt(prompt) {
|
|
83
|
+
return prompt
|
|
84
|
+
.replace(/```[\s\S]*?```/g, ' ')
|
|
85
|
+
.replace(/`[^`]*`/g, ' ')
|
|
86
|
+
.replace(/https?:\/\/\S+/g, ' ')
|
|
87
|
+
.replace(/[@#][\w.-]+/g, ' ')
|
|
88
|
+
.replace(/[“”"']/g, '')
|
|
89
|
+
.replace(/\s+/g, ' ')
|
|
90
|
+
.trim();
|
|
91
|
+
}
|
|
92
|
+
function toTitleCase(word) {
|
|
93
|
+
return word ? word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() : word;
|
|
94
|
+
}
|
|
95
|
+
function trimLatinTitle(input) {
|
|
96
|
+
const words = input
|
|
97
|
+
.replace(LEADING_LATIN_FILLER, '')
|
|
98
|
+
.replace(/[^\p{L}\p{N}\s-]/gu, ' ')
|
|
99
|
+
.split(/\s+/)
|
|
100
|
+
.filter(Boolean)
|
|
101
|
+
.filter((word) => !LATIN_STOP_WORDS.has(word.toLowerCase()))
|
|
102
|
+
.slice(0, MAX_LATIN_WORDS);
|
|
103
|
+
// Applied after the cap, because the cap is what strands these words in the first place.
|
|
104
|
+
while (words.length > 0 && LATIN_NEVER_TRAILING.has(words[words.length - 1].toLowerCase())) {
|
|
105
|
+
words.pop();
|
|
106
|
+
}
|
|
107
|
+
return words.map(toTitleCase).join(' ');
|
|
108
|
+
}
|
|
109
|
+
function trimCjkTitle(input) {
|
|
110
|
+
let title = input.trim();
|
|
111
|
+
for (const pattern of LEADING_CJK_FILLER)
|
|
112
|
+
title = title.replace(pattern, '').trim();
|
|
113
|
+
// Cut at the first sentence-ending punctuation, then drop spacing — CJK titles do not use it.
|
|
114
|
+
title = title.replace(/[,。!?;:,.!?;:].*$/, '').replace(/\s+/g, '');
|
|
115
|
+
return title.slice(0, MAX_CJK_LENGTH);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns a short display title for a conversation, or `''` when the prompt yields nothing
|
|
119
|
+
* usable (a bare URL, a lone code fence, pure punctuation). Callers should treat `''` as "leave
|
|
120
|
+
* the conversation untitled" rather than substituting the raw prompt — a list row showing 400
|
|
121
|
+
* characters of pasted code is worse than one showing "Untitled".
|
|
122
|
+
*
|
|
123
|
+
* @complexity O(n) in prompt length; no allocation beyond the intermediate strings.
|
|
124
|
+
*/
|
|
125
|
+
export function deriveConversationTitle(prompt) {
|
|
126
|
+
const cleaned = cleanPrompt(prompt);
|
|
127
|
+
if (!cleaned)
|
|
128
|
+
return '';
|
|
129
|
+
const firstClause = cleaned.split(/[\n\r。!?!?]/)[0]?.trim() ?? cleaned;
|
|
130
|
+
if (!firstClause)
|
|
131
|
+
return '';
|
|
132
|
+
const title = CJK_PATTERN.test(firstClause) ? trimCjkTitle(firstClause) : trimLatinTitle(firstClause);
|
|
133
|
+
// Truncated without an ellipsis: this is a working title, not prose, and a `…` would end up stored
|
|
134
|
+
// and shown as if the author wrote it.
|
|
135
|
+
return title.length > MAX_TITLE_CHARS ? title.slice(0, MAX_TITLE_CHARS).trimEnd() : title;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=title.js.map
|