netra-artifacts 0.1.0-alpha.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/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +239 -0
- package/dist/artifacts/artifactEnvelope.d.ts +46 -0
- package/dist/artifacts/artifactEnvelope.d.ts.map +1 -0
- package/dist/artifacts/artifactEnvelope.js +217 -0
- package/dist/artifacts/artifactEnvelope.js.map +1 -0
- package/dist/artifacts/artifactStatus.d.ts +9 -0
- package/dist/artifacts/artifactStatus.d.ts.map +1 -0
- package/dist/artifacts/artifactStatus.js +10 -0
- package/dist/artifacts/artifactStatus.js.map +1 -0
- package/dist/artifacts/artifactStore.d.ts +15 -0
- package/dist/artifacts/artifactStore.d.ts.map +1 -0
- package/dist/artifacts/artifactStore.js +35 -0
- package/dist/artifacts/artifactStore.js.map +1 -0
- package/dist/artifacts/htmlArtifact.d.ts +10 -0
- package/dist/artifacts/htmlArtifact.d.ts.map +1 -0
- package/dist/artifacts/htmlArtifact.js +20 -0
- package/dist/artifacts/htmlArtifact.js.map +1 -0
- package/dist/artifacts/index.d.ts +5 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +5 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/circuit-breaker/circuitBreaker.d.ts +35 -0
- package/dist/circuit-breaker/circuitBreaker.d.ts.map +1 -0
- package/dist/circuit-breaker/circuitBreaker.js +59 -0
- package/dist/circuit-breaker/circuitBreaker.js.map +1 -0
- package/dist/circuit-breaker/index.d.ts +3 -0
- package/dist/circuit-breaker/index.d.ts.map +1 -0
- package/dist/circuit-breaker/index.js +3 -0
- package/dist/circuit-breaker/index.js.map +1 -0
- package/dist/circuit-breaker/memoryCircuitStore.d.ts +24 -0
- package/dist/circuit-breaker/memoryCircuitStore.d.ts.map +1 -0
- package/dist/circuit-breaker/memoryCircuitStore.js +12 -0
- package/dist/circuit-breaker/memoryCircuitStore.js.map +1 -0
- package/dist/classifier/classifierPrompt.d.ts +7 -0
- package/dist/classifier/classifierPrompt.d.ts.map +1 -0
- package/dist/classifier/classifierPrompt.js +43 -0
- package/dist/classifier/classifierPrompt.js.map +1 -0
- package/dist/classifier/classifyMode.d.ts +21 -0
- package/dist/classifier/classifyMode.d.ts.map +1 -0
- package/dist/classifier/classifyMode.js +50 -0
- package/dist/classifier/classifyMode.js.map +1 -0
- package/dist/classifier/index.d.ts +4 -0
- package/dist/classifier/index.d.ts.map +1 -0
- package/dist/classifier/index.js +4 -0
- package/dist/classifier/index.js.map +1 -0
- package/dist/classifier/rules.d.ts +13 -0
- package/dist/classifier/rules.d.ts.map +1 -0
- package/dist/classifier/rules.js +118 -0
- package/dist/classifier/rules.js.map +1 -0
- package/dist/client/ArtifactChat.d.ts +15 -0
- package/dist/client/ArtifactChat.d.ts.map +1 -0
- package/dist/client/ArtifactChat.js +62 -0
- package/dist/client/ArtifactChat.js.map +1 -0
- package/dist/client/ArtifactMessage.d.ts +24 -0
- package/dist/client/ArtifactMessage.d.ts.map +1 -0
- package/dist/client/ArtifactMessage.js +29 -0
- package/dist/client/ArtifactMessage.js.map +1 -0
- package/dist/client/MarkdownMessage.d.ts +12 -0
- package/dist/client/MarkdownMessage.d.ts.map +1 -0
- package/dist/client/MarkdownMessage.js +141 -0
- package/dist/client/MarkdownMessage.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/useArtifactStream.d.ts +9 -0
- package/dist/client/useArtifactStream.d.ts.map +1 -0
- package/dist/client/useArtifactStream.js +210 -0
- package/dist/client/useArtifactStream.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -0
- package/dist/constants/defaults.d.ts +17 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +38 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/constants/events.d.ts +16 -0
- package/dist/constants/events.d.ts.map +1 -0
- package/dist/constants/events.js +16 -0
- package/dist/constants/events.js.map +1 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +4 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/sandbox.d.ts +19 -0
- package/dist/constants/sandbox.d.ts.map +1 -0
- package/dist/constants/sandbox.js +24 -0
- package/dist/constants/sandbox.js.map +1 -0
- package/dist/core/createArtifactResponse.d.ts +5 -0
- package/dist/core/createArtifactResponse.d.ts.map +1 -0
- package/dist/core/createArtifactResponse.js +16 -0
- package/dist/core/createArtifactResponse.js.map +1 -0
- package/dist/core/createArtifactStream.d.ts +9 -0
- package/dist/core/createArtifactStream.d.ts.map +1 -0
- package/dist/core/createArtifactStream.js +34 -0
- package/dist/core/createArtifactStream.js.map +1 -0
- package/dist/core/createIds.d.ts +3 -0
- package/dist/core/createIds.d.ts.map +1 -0
- package/dist/core/createIds.js +13 -0
- package/dist/core/createIds.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lifecycle.d.ts +35 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +81 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/parseArtifactEnvelope.d.ts +2 -0
- package/dist/core/parseArtifactEnvelope.d.ts.map +1 -0
- package/dist/core/parseArtifactEnvelope.js +3 -0
- package/dist/core/parseArtifactEnvelope.js.map +1 -0
- package/dist/errors/ArtifactParseError.d.ts +10 -0
- package/dist/errors/ArtifactParseError.d.ts.map +1 -0
- package/dist/errors/ArtifactParseError.js +10 -0
- package/dist/errors/ArtifactParseError.js.map +1 -0
- package/dist/errors/ClassificationError.d.ts +13 -0
- package/dist/errors/ClassificationError.d.ts.map +1 -0
- package/dist/errors/ClassificationError.js +13 -0
- package/dist/errors/ClassificationError.js.map +1 -0
- package/dist/errors/StreamError.d.ts +11 -0
- package/dist/errors/StreamError.d.ts.map +1 -0
- package/dist/errors/StreamError.js +11 -0
- package/dist/errors/StreamError.js.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +4 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/iframe/HtmlArtifactCard.d.ts +9 -0
- package/dist/iframe/HtmlArtifactCard.d.ts.map +1 -0
- package/dist/iframe/HtmlArtifactCard.js +117 -0
- package/dist/iframe/HtmlArtifactCard.js.map +1 -0
- package/dist/iframe/HtmlArtifactCodeView.d.ts +7 -0
- package/dist/iframe/HtmlArtifactCodeView.d.ts.map +1 -0
- package/dist/iframe/HtmlArtifactCodeView.js +20 -0
- package/dist/iframe/HtmlArtifactCodeView.js.map +1 -0
- package/dist/iframe/HtmlArtifactModal.d.ts +16 -0
- package/dist/iframe/HtmlArtifactModal.d.ts.map +1 -0
- package/dist/iframe/HtmlArtifactModal.js +99 -0
- package/dist/iframe/HtmlArtifactModal.js.map +1 -0
- package/dist/iframe/HtmlArtifactPreview.d.ts +15 -0
- package/dist/iframe/HtmlArtifactPreview.d.ts.map +1 -0
- package/dist/iframe/HtmlArtifactPreview.js +214 -0
- package/dist/iframe/HtmlArtifactPreview.js.map +1 -0
- package/dist/iframe/HtmlArtifactToolbar.d.ts +20 -0
- package/dist/iframe/HtmlArtifactToolbar.d.ts.map +1 -0
- package/dist/iframe/HtmlArtifactToolbar.js +14 -0
- package/dist/iframe/HtmlArtifactToolbar.js.map +1 -0
- package/dist/iframe/iframeSizing.d.ts +22 -0
- package/dist/iframe/iframeSizing.d.ts.map +1 -0
- package/dist/iframe/iframeSizing.js +74 -0
- package/dist/iframe/iframeSizing.js.map +1 -0
- package/dist/iframe/iframeSrcDoc.d.ts +34 -0
- package/dist/iframe/iframeSrcDoc.d.ts.map +1 -0
- package/dist/iframe/iframeSrcDoc.js +236 -0
- package/dist/iframe/iframeSrcDoc.js.map +1 -0
- package/dist/iframe/index.d.ts +15 -0
- package/dist/iframe/index.d.ts.map +1 -0
- package/dist/iframe/index.js +9 -0
- package/dist/iframe/index.js.map +1 -0
- package/dist/iframe/styles.d.ts +10 -0
- package/dist/iframe/styles.d.ts.map +1 -0
- package/dist/iframe/styles.js +181 -0
- package/dist/iframe/styles.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/htmlArtifactPrompt.d.ts +15 -0
- package/dist/prompts/htmlArtifactPrompt.d.ts.map +1 -0
- package/dist/prompts/htmlArtifactPrompt.js +248 -0
- package/dist/prompts/htmlArtifactPrompt.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +4 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/markdownPrompt.d.ts +3 -0
- package/dist/prompts/markdownPrompt.d.ts.map +1 -0
- package/dist/prompts/markdownPrompt.js +10 -0
- package/dist/prompts/markdownPrompt.js.map +1 -0
- package/dist/prompts/systemPrompt.d.ts +3 -0
- package/dist/prompts/systemPrompt.d.ts.map +1 -0
- package/dist/prompts/systemPrompt.js +3 -0
- package/dist/prompts/systemPrompt.js.map +1 -0
- package/dist/sanitizer/dangerousPatterns.d.ts +41 -0
- package/dist/sanitizer/dangerousPatterns.d.ts.map +1 -0
- package/dist/sanitizer/dangerousPatterns.js +41 -0
- package/dist/sanitizer/dangerousPatterns.js.map +1 -0
- package/dist/sanitizer/index.d.ts +4 -0
- package/dist/sanitizer/index.d.ts.map +1 -0
- package/dist/sanitizer/index.js +4 -0
- package/dist/sanitizer/index.js.map +1 -0
- package/dist/sanitizer/sanitizeConfig.d.ts +4 -0
- package/dist/sanitizer/sanitizeConfig.d.ts.map +1 -0
- package/dist/sanitizer/sanitizeConfig.js +10 -0
- package/dist/sanitizer/sanitizeConfig.js.map +1 -0
- package/dist/sanitizer/sanitizeHtml.d.ts +20 -0
- package/dist/sanitizer/sanitizeHtml.d.ts.map +1 -0
- package/dist/sanitizer/sanitizeHtml.js +81 -0
- package/dist/sanitizer/sanitizeHtml.js.map +1 -0
- package/dist/server/config.d.ts +6 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +68 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/createArtifactStreamResponse.d.ts +9 -0
- package/dist/server/createArtifactStreamResponse.d.ts.map +1 -0
- package/dist/server/createArtifactStreamResponse.js +104 -0
- package/dist/server/createArtifactStreamResponse.js.map +1 -0
- package/dist/server/createHtmlArtifactStream.d.ts +30 -0
- package/dist/server/createHtmlArtifactStream.d.ts.map +1 -0
- package/dist/server/createHtmlArtifactStream.js +115 -0
- package/dist/server/createHtmlArtifactStream.js.map +1 -0
- package/dist/server/createMarkdownStream.d.ts +13 -0
- package/dist/server/createMarkdownStream.d.ts.map +1 -0
- package/dist/server/createMarkdownStream.js +27 -0
- package/dist/server/createMarkdownStream.js.map +1 -0
- package/dist/server/createSseResponse.d.ts +7 -0
- package/dist/server/createSseResponse.d.ts.map +1 -0
- package/dist/server/createSseResponse.js +11 -0
- package/dist/server/createSseResponse.js.map +1 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +12 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +3 -0
- package/dist/server.js.map +1 -0
- package/dist/stream/assembleDocument.d.ts +42 -0
- package/dist/stream/assembleDocument.d.ts.map +1 -0
- package/dist/stream/assembleDocument.js +104 -0
- package/dist/stream/assembleDocument.js.map +1 -0
- package/dist/stream/buffering.d.ts +37 -0
- package/dist/stream/buffering.d.ts.map +1 -0
- package/dist/stream/buffering.js +97 -0
- package/dist/stream/buffering.js.map +1 -0
- package/dist/stream/debounce.d.ts +12 -0
- package/dist/stream/debounce.d.ts.map +1 -0
- package/dist/stream/debounce.js +36 -0
- package/dist/stream/debounce.js.map +1 -0
- package/dist/stream/decoder.d.ts +17 -0
- package/dist/stream/decoder.d.ts.map +1 -0
- package/dist/stream/decoder.js +71 -0
- package/dist/stream/decoder.js.map +1 -0
- package/dist/stream/encoder.d.ts +12 -0
- package/dist/stream/encoder.d.ts.map +1 -0
- package/dist/stream/encoder.js +19 -0
- package/dist/stream/encoder.js.map +1 -0
- package/dist/stream/events.d.ts +20 -0
- package/dist/stream/events.d.ts.map +1 -0
- package/dist/stream/events.js +65 -0
- package/dist/stream/events.js.map +1 -0
- package/dist/stream/index.d.ts +9 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +9 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/predictiveHtmlParser.d.ts +52 -0
- package/dist/stream/predictiveHtmlParser.d.ts.map +1 -0
- package/dist/stream/predictiveHtmlParser.js +252 -0
- package/dist/stream/predictiveHtmlParser.js.map +1 -0
- package/dist/stream/sse.d.ts +7 -0
- package/dist/stream/sse.d.ts.map +1 -0
- package/dist/stream/sse.js +33 -0
- package/dist/stream/sse.js.map +1 -0
- package/dist/types/artifact.d.ts +88 -0
- package/dist/types/artifact.d.ts.map +1 -0
- package/dist/types/artifact.js +2 -0
- package/dist/types/artifact.js.map +1 -0
- package/dist/types/client.d.ts +98 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/client.js +2 -0
- package/dist/types/client.js.map +1 -0
- package/dist/types/config.d.ts +23 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +9 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +2 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/server.d.ts +111 -0
- package/dist/types/server.d.ts.map +1 -0
- package/dist/types/server.js +2 -0
- package/dist/types/server.js.map +1 -0
- package/dist/types/stream.d.ts +60 -0
- package/dist/types/stream.d.ts.map +1 -0
- package/dist/types/stream.js +7 -0
- package/dist/types/stream.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/invariant.d.ts +6 -0
- package/dist/utils/invariant.d.ts.map +1 -0
- package/dist/utils/invariant.js +10 -0
- package/dist/utils/invariant.js.map +1 -0
- package/dist/utils/isBrowser.d.ts +3 -0
- package/dist/utils/isBrowser.d.ts.map +1 -0
- package/dist/utils/isBrowser.js +3 -0
- package/dist/utils/isBrowser.js.map +1 -0
- package/dist/utils/mergeConfig.d.ts +6 -0
- package/dist/utils/mergeConfig.d.ts.map +1 -0
- package/dist/utils/mergeConfig.js +17 -0
- package/dist/utils/mergeConfig.js.map +1 -0
- package/dist/utils/noop.d.ts +3 -0
- package/dist/utils/noop.d.ts.map +1 -0
- package/dist/utils/noop.js +3 -0
- package/dist/utils/noop.js.map +1 -0
- package/dist/utils/safeJsonParse.d.ts +7 -0
- package/dist/utils/safeJsonParse.d.ts.map +1 -0
- package/dist/utils/safeJsonParse.js +62 -0
- package/dist/utils/safeJsonParse.js.map +1 -0
- package/dist-cjs/artifacts/artifactEnvelope.js +224 -0
- package/dist-cjs/artifacts/artifactEnvelope.js.map +1 -0
- package/dist-cjs/artifacts/artifactStatus.js +14 -0
- package/dist-cjs/artifacts/artifactStatus.js.map +1 -0
- package/dist-cjs/artifacts/artifactStore.js +39 -0
- package/dist-cjs/artifacts/artifactStore.js.map +1 -0
- package/dist-cjs/artifacts/htmlArtifact.js +24 -0
- package/dist-cjs/artifacts/htmlArtifact.js.map +1 -0
- package/dist-cjs/artifacts/index.js +21 -0
- package/dist-cjs/artifacts/index.js.map +1 -0
- package/dist-cjs/circuit-breaker/circuitBreaker.js +63 -0
- package/dist-cjs/circuit-breaker/circuitBreaker.js.map +1 -0
- package/dist-cjs/circuit-breaker/index.js +19 -0
- package/dist-cjs/circuit-breaker/index.js.map +1 -0
- package/dist-cjs/circuit-breaker/memoryCircuitStore.js +16 -0
- package/dist-cjs/circuit-breaker/memoryCircuitStore.js.map +1 -0
- package/dist-cjs/classifier/classifierPrompt.js +47 -0
- package/dist-cjs/classifier/classifierPrompt.js.map +1 -0
- package/dist-cjs/classifier/classifyMode.js +53 -0
- package/dist-cjs/classifier/classifyMode.js.map +1 -0
- package/dist-cjs/classifier/index.js +20 -0
- package/dist-cjs/classifier/index.js.map +1 -0
- package/dist-cjs/classifier/rules.js +121 -0
- package/dist-cjs/classifier/rules.js.map +1 -0
- package/dist-cjs/client/ArtifactChat.js +98 -0
- package/dist-cjs/client/ArtifactChat.js.map +1 -0
- package/dist-cjs/client/ArtifactMessage.js +32 -0
- package/dist-cjs/client/ArtifactMessage.js.map +1 -0
- package/dist-cjs/client/MarkdownMessage.js +177 -0
- package/dist-cjs/client/MarkdownMessage.js.map +1 -0
- package/dist-cjs/client/index.js +20 -0
- package/dist-cjs/client/index.js.map +1 -0
- package/dist-cjs/client/useArtifactStream.js +246 -0
- package/dist-cjs/client/useArtifactStream.js.map +1 -0
- package/dist-cjs/client.js +20 -0
- package/dist-cjs/client.js.map +1 -0
- package/dist-cjs/constants/defaults.js +41 -0
- package/dist-cjs/constants/defaults.js.map +1 -0
- package/dist-cjs/constants/events.js +19 -0
- package/dist-cjs/constants/events.js.map +1 -0
- package/dist-cjs/constants/index.js +20 -0
- package/dist-cjs/constants/index.js.map +1 -0
- package/dist-cjs/constants/sandbox.js +27 -0
- package/dist-cjs/constants/sandbox.js.map +1 -0
- package/dist-cjs/core/createArtifactResponse.js +20 -0
- package/dist-cjs/core/createArtifactResponse.js.map +1 -0
- package/dist-cjs/core/createArtifactStream.js +37 -0
- package/dist-cjs/core/createArtifactStream.js.map +1 -0
- package/dist-cjs/core/createIds.js +17 -0
- package/dist-cjs/core/createIds.js.map +1 -0
- package/dist-cjs/core/index.js +22 -0
- package/dist-cjs/core/index.js.map +1 -0
- package/dist-cjs/core/lifecycle.js +86 -0
- package/dist-cjs/core/lifecycle.js.map +1 -0
- package/dist-cjs/core/parseArtifactEnvelope.js +8 -0
- package/dist-cjs/core/parseArtifactEnvelope.js.map +1 -0
- package/dist-cjs/errors/ArtifactParseError.js +14 -0
- package/dist-cjs/errors/ArtifactParseError.js.map +1 -0
- package/dist-cjs/errors/ClassificationError.js +17 -0
- package/dist-cjs/errors/ClassificationError.js.map +1 -0
- package/dist-cjs/errors/StreamError.js +15 -0
- package/dist-cjs/errors/StreamError.js.map +1 -0
- package/dist-cjs/errors/index.js +20 -0
- package/dist-cjs/errors/index.js.map +1 -0
- package/dist-cjs/iframe/HtmlArtifactCard.js +153 -0
- package/dist-cjs/iframe/HtmlArtifactCard.js.map +1 -0
- package/dist-cjs/iframe/HtmlArtifactCodeView.js +23 -0
- package/dist-cjs/iframe/HtmlArtifactCodeView.js.map +1 -0
- package/dist-cjs/iframe/HtmlArtifactModal.js +135 -0
- package/dist-cjs/iframe/HtmlArtifactModal.js.map +1 -0
- package/dist-cjs/iframe/HtmlArtifactPreview.js +250 -0
- package/dist-cjs/iframe/HtmlArtifactPreview.js.map +1 -0
- package/dist-cjs/iframe/HtmlArtifactToolbar.js +17 -0
- package/dist-cjs/iframe/HtmlArtifactToolbar.js.map +1 -0
- package/dist-cjs/iframe/iframeSizing.js +77 -0
- package/dist-cjs/iframe/iframeSizing.js.map +1 -0
- package/dist-cjs/iframe/iframeSrcDoc.js +241 -0
- package/dist-cjs/iframe/iframeSrcDoc.js.map +1 -0
- package/dist-cjs/iframe/index.js +22 -0
- package/dist-cjs/iframe/index.js.map +1 -0
- package/dist-cjs/iframe/styles.js +218 -0
- package/dist-cjs/iframe/styles.js.map +1 -0
- package/dist-cjs/index.js +52 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/prompts/htmlArtifactPrompt.js +252 -0
- package/dist-cjs/prompts/htmlArtifactPrompt.js.map +1 -0
- package/dist-cjs/prompts/index.js +20 -0
- package/dist-cjs/prompts/index.js.map +1 -0
- package/dist-cjs/prompts/markdownPrompt.js +13 -0
- package/dist-cjs/prompts/markdownPrompt.js.map +1 -0
- package/dist-cjs/prompts/systemPrompt.js +6 -0
- package/dist-cjs/prompts/systemPrompt.js.map +1 -0
- package/dist-cjs/sanitizer/dangerousPatterns.js +44 -0
- package/dist-cjs/sanitizer/dangerousPatterns.js.map +1 -0
- package/dist-cjs/sanitizer/index.js +43 -0
- package/dist-cjs/sanitizer/index.js.map +1 -0
- package/dist-cjs/sanitizer/sanitizeConfig.js +13 -0
- package/dist-cjs/sanitizer/sanitizeConfig.js.map +1 -0
- package/dist-cjs/sanitizer/sanitizeHtml.js +86 -0
- package/dist-cjs/sanitizer/sanitizeHtml.js.map +1 -0
- package/dist-cjs/server/config.js +72 -0
- package/dist-cjs/server/config.js.map +1 -0
- package/dist-cjs/server/createArtifactStreamResponse.js +107 -0
- package/dist-cjs/server/createArtifactStreamResponse.js.map +1 -0
- package/dist-cjs/server/createHtmlArtifactStream.js +119 -0
- package/dist-cjs/server/createHtmlArtifactStream.js.map +1 -0
- package/dist-cjs/server/createMarkdownStream.js +31 -0
- package/dist-cjs/server/createMarkdownStream.js.map +1 -0
- package/dist-cjs/server/createSseResponse.js +14 -0
- package/dist-cjs/server/createSseResponse.js.map +1 -0
- package/dist-cjs/server/index.js +34 -0
- package/dist-cjs/server/index.js.map +1 -0
- package/dist-cjs/server.js +19 -0
- package/dist-cjs/server.js.map +1 -0
- package/dist-cjs/stream/assembleDocument.js +109 -0
- package/dist-cjs/stream/assembleDocument.js.map +1 -0
- package/dist-cjs/stream/buffering.js +102 -0
- package/dist-cjs/stream/buffering.js.map +1 -0
- package/dist-cjs/stream/debounce.js +39 -0
- package/dist-cjs/stream/debounce.js.map +1 -0
- package/dist-cjs/stream/decoder.js +75 -0
- package/dist-cjs/stream/decoder.js.map +1 -0
- package/dist-cjs/stream/encoder.js +24 -0
- package/dist-cjs/stream/encoder.js.map +1 -0
- package/dist-cjs/stream/events.js +69 -0
- package/dist-cjs/stream/events.js.map +1 -0
- package/dist-cjs/stream/index.js +25 -0
- package/dist-cjs/stream/index.js.map +1 -0
- package/dist-cjs/stream/predictiveHtmlParser.js +256 -0
- package/dist-cjs/stream/predictiveHtmlParser.js.map +1 -0
- package/dist-cjs/stream/sse.js +36 -0
- package/dist-cjs/stream/sse.js.map +1 -0
- package/dist-cjs/types/artifact.js +3 -0
- package/dist-cjs/types/artifact.js.map +1 -0
- package/dist-cjs/types/client.js +3 -0
- package/dist-cjs/types/client.js.map +1 -0
- package/dist-cjs/types/config.js +3 -0
- package/dist-cjs/types/config.js.map +1 -0
- package/dist-cjs/types/errors.js +3 -0
- package/dist-cjs/types/errors.js.map +1 -0
- package/dist-cjs/types/index.js +3 -0
- package/dist-cjs/types/index.js.map +1 -0
- package/dist-cjs/types/server.js +3 -0
- package/dist-cjs/types/server.js.map +1 -0
- package/dist-cjs/types/stream.js +8 -0
- package/dist-cjs/types/stream.js.map +1 -0
- package/dist-cjs/utils/index.js +22 -0
- package/dist-cjs/utils/index.js.map +1 -0
- package/dist-cjs/utils/invariant.js +13 -0
- package/dist-cjs/utils/invariant.js.map +1 -0
- package/dist-cjs/utils/isBrowser.js +6 -0
- package/dist-cjs/utils/isBrowser.js.map +1 -0
- package/dist-cjs/utils/mergeConfig.js +20 -0
- package/dist-cjs/utils/mergeConfig.js.map +1 -0
- package/dist-cjs/utils/noop.js +7 -0
- package/dist-cjs/utils/noop.js.map +1 -0
- package/dist-cjs/utils/safeJsonParse.js +65 -0
- package/dist-cjs/utils/safeJsonParse.js.map +1 -0
- package/package.json +115 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `netra` are documented here. This project
|
|
4
|
+
adheres to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## [0.1.0] - 2026-05-29
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Initial experimental release.
|
|
11
|
+
- `createArtifactStreamResponse()` server helper — auto-classifies a request as
|
|
12
|
+
`markdown` or `html_artifact`, then streams an SSE response over the
|
|
13
|
+
`ArtifactStreamEvent` protocol.
|
|
14
|
+
- Vercel AI SDK integration via `streamText` / `generateText` (no RSC, no `streamUI`).
|
|
15
|
+
- Mode classifier with model-based classification and a heuristic rule fallback.
|
|
16
|
+
- `<assistant_message>` / `<html_artifact>` envelope parser with fail-open behavior.
|
|
17
|
+
- Static-only HTML sanitizer (strips `<script>`, event handlers, `javascript:`
|
|
18
|
+
URLs, external CSS/JS; preserves inline styles, `<style>`, SVG, and forms).
|
|
19
|
+
- `useArtifactStream()` React hook plus `ArtifactChat`, `ArtifactMessage`,
|
|
20
|
+
`MarkdownMessage` components.
|
|
21
|
+
- Seamless sandboxed iframe rendering: `HtmlArtifactCard`, `HtmlArtifactPreview`,
|
|
22
|
+
`HtmlArtifactModal`, `HtmlArtifactToolbar`, `HtmlArtifactCodeView`.
|
|
23
|
+
- Snapshot buffering that keeps the last valid snapshot while partial HTML streams.
|
|
24
|
+
- In-memory circuit breaker that falls back to markdown after repeated failures.
|
|
25
|
+
- Dual ESM + CJS builds with subpath exports.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Netra Predictive HTML Parser
|
|
2
|
+
|
|
3
|
+
Experimental dependency-free package for streaming AI-generated HTML into
|
|
4
|
+
sandboxed iframe previews. Bring any model SDK that can produce text chunks.
|
|
5
|
+
|
|
6
|
+
The high-level server helper is provider-agnostic: pass a
|
|
7
|
+
`generateTextStream(args) => AsyncIterable<string>` adapter. For lower-level
|
|
8
|
+
integrations, `streamHtmlArtifactFromTextStream` accepts raw text chunks
|
|
9
|
+
directly.
|
|
10
|
+
|
|
11
|
+
Netra keeps two versions of streamed HTML:
|
|
12
|
+
|
|
13
|
+
- **Raw HTML:** the exact model output, never mutated by predictions
|
|
14
|
+
- **Snapshot HTML:** a temporary, sanitized, iframe-safe projection with missing
|
|
15
|
+
closing tags predicted from the parser stack
|
|
16
|
+
|
|
17
|
+
This lets a frontend render partial HTML while the model is still producing the
|
|
18
|
+
document.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install netra
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Add whatever provider SDK you want:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @ai-sdk/google
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Backend
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
36
|
+
import { generateText, streamText } from "ai";
|
|
37
|
+
import { createArtifactStreamResponse } from "netra/server";
|
|
38
|
+
|
|
39
|
+
const google = createGoogleGenerativeAI({
|
|
40
|
+
apiKey: process.env.GOOGLE_API_KEY,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export async function POST(req: Request) {
|
|
44
|
+
const { messages } = await req.json();
|
|
45
|
+
const model = google("gemini-2.5-flash");
|
|
46
|
+
|
|
47
|
+
return createArtifactStreamResponse({
|
|
48
|
+
messages,
|
|
49
|
+
generateTextStream: (args) => streamText({ model, ...args }).textStream,
|
|
50
|
+
generateText: async (args) => (await generateText({ model, ...args })).text,
|
|
51
|
+
mode: "auto",
|
|
52
|
+
snapshotIntervalMs: 0,
|
|
53
|
+
allowExternalFonts: true,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## LangChain Adapter Pattern
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import {
|
|
62
|
+
HTML_ARTIFACT_SYSTEM_PROMPT,
|
|
63
|
+
createSseResponse,
|
|
64
|
+
event,
|
|
65
|
+
streamHtmlArtifactFromTextStream,
|
|
66
|
+
} from "netra/server";
|
|
67
|
+
|
|
68
|
+
async function* toText(chunks: AsyncIterable<unknown>) {
|
|
69
|
+
for await (const chunk of chunks) {
|
|
70
|
+
if (typeof chunk === "string") yield chunk;
|
|
71
|
+
else if (chunk && typeof chunk === "object" && "content" in chunk) {
|
|
72
|
+
yield String((chunk as { content: unknown }).content ?? "");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function POST(req: Request) {
|
|
78
|
+
const { messages } = await req.json();
|
|
79
|
+
|
|
80
|
+
return createSseResponse(async (emit) => {
|
|
81
|
+
emit(event.mode("html_artifact"));
|
|
82
|
+
|
|
83
|
+
const stream = await model.stream([
|
|
84
|
+
["system", HTML_ARTIFACT_SYSTEM_PROMPT],
|
|
85
|
+
...messages.map((m: { role: string; content: string }) => [
|
|
86
|
+
m.role,
|
|
87
|
+
m.content,
|
|
88
|
+
]),
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
await streamHtmlArtifactFromTextStream(
|
|
92
|
+
{
|
|
93
|
+
textStream: toText(stream),
|
|
94
|
+
sanitize: {
|
|
95
|
+
allowForms: true,
|
|
96
|
+
allowScripts: false,
|
|
97
|
+
allowInlineStyles: true,
|
|
98
|
+
allowStyleTags: true,
|
|
99
|
+
allowSvg: true,
|
|
100
|
+
allowExternalFonts: false,
|
|
101
|
+
},
|
|
102
|
+
snapshotIntervalMs: 0,
|
|
103
|
+
},
|
|
104
|
+
emit,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
emit(event.done());
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Frontend
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
"use client";
|
|
116
|
+
|
|
117
|
+
import { ArtifactMessage, useArtifactStream } from "netra/client";
|
|
118
|
+
|
|
119
|
+
export function Chat() {
|
|
120
|
+
const { messages, artifacts, status, sendMessage } = useArtifactStream({
|
|
121
|
+
endpoint: "/api/chat",
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div>
|
|
126
|
+
{messages.map((message) => (
|
|
127
|
+
<ArtifactMessage
|
|
128
|
+
key={message.id}
|
|
129
|
+
message={message}
|
|
130
|
+
artifacts={artifacts}
|
|
131
|
+
cardProps={{
|
|
132
|
+
variant: "glass",
|
|
133
|
+
previewOptions: {
|
|
134
|
+
allowExternalFonts: true,
|
|
135
|
+
autoResize: true,
|
|
136
|
+
debounceMs: 0,
|
|
137
|
+
},
|
|
138
|
+
}}
|
|
139
|
+
/>
|
|
140
|
+
))}
|
|
141
|
+
|
|
142
|
+
<button
|
|
143
|
+
disabled={status === "submitted" || status === "streaming"}
|
|
144
|
+
onClick={() => sendMessage("Create a sign-up form")}
|
|
145
|
+
>
|
|
146
|
+
Generate
|
|
147
|
+
</button>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Direct Parser Usage
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { PredictiveHtmlParser } from "netra/stream";
|
|
157
|
+
|
|
158
|
+
const parser = new PredictiveHtmlParser();
|
|
159
|
+
|
|
160
|
+
const frameA = parser.push("<body><form>");
|
|
161
|
+
// "<body><form></form></body>"
|
|
162
|
+
|
|
163
|
+
parser.committedHtml;
|
|
164
|
+
// "<body><form>"
|
|
165
|
+
|
|
166
|
+
const frameB = parser.push('<input type="email" />');
|
|
167
|
+
// '<body><form><input type="email" /></form></body>'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## One-Shot Assembly
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { assembleStreamingHtml } from "netra/stream";
|
|
174
|
+
|
|
175
|
+
const result = assembleStreamingHtml("<html><body><main><h1>Hello");
|
|
176
|
+
|
|
177
|
+
result.html;
|
|
178
|
+
// "<html><body><main><h1>Hello</h1></main></body></html>"
|
|
179
|
+
|
|
180
|
+
result.renderable;
|
|
181
|
+
// true
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Exports
|
|
185
|
+
|
|
186
|
+
| Import | Purpose |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| `netra` | Isomorphic helpers, types, parser, sanitizer |
|
|
189
|
+
| `netra/server` | Server response helpers for SSE |
|
|
190
|
+
| `netra/client` | React hook and UI components |
|
|
191
|
+
| `netra/iframe` | Iframe card and preview primitives |
|
|
192
|
+
| `netra/stream` | Parser, SSE, buffering utilities |
|
|
193
|
+
| `netra/sanitizer` | Sanitizer helpers |
|
|
194
|
+
| `netra/classifier` | Auto-mode classifier |
|
|
195
|
+
| `netra/types` | Public types |
|
|
196
|
+
|
|
197
|
+
## Protocol
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
type ArtifactStreamEvent =
|
|
201
|
+
| { type: "mode"; mode: "markdown" | "html_artifact" }
|
|
202
|
+
| { type: "message_start"; messageId: string }
|
|
203
|
+
| { type: "message_delta"; messageId: string; delta: string }
|
|
204
|
+
| { type: "message_done"; messageId: string; content: string }
|
|
205
|
+
| { type: "artifact_start"; artifactId: string; title: string; artifactType: "html" }
|
|
206
|
+
| { type: "artifact_delta"; artifactId: string; delta: string }
|
|
207
|
+
| { type: "artifact_snapshot"; artifactId: string; html: string }
|
|
208
|
+
| { type: "artifact_done"; artifactId: string; html: string }
|
|
209
|
+
| { type: "error"; message: string; recoverable: boolean }
|
|
210
|
+
| { type: "done" };
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Security
|
|
214
|
+
|
|
215
|
+
Artifacts are static HTML/CSS:
|
|
216
|
+
|
|
217
|
+
- Scripts are stripped
|
|
218
|
+
- Event handler attributes are stripped
|
|
219
|
+
- Dangerous URLs are stripped
|
|
220
|
+
- Iframes, embeds, object tags, and refresh meta tags are stripped
|
|
221
|
+
- The preview iframe never receives `allow-scripts`
|
|
222
|
+
- `allowExternalFonts` only keeps approved Google Fonts hosts
|
|
223
|
+
|
|
224
|
+
Use Netra for safe previews of generated static HTML, not for executing
|
|
225
|
+
generated application logic.
|
|
226
|
+
|
|
227
|
+
## Checks
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npm run typecheck
|
|
231
|
+
npm run build
|
|
232
|
+
npm test
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Status
|
|
236
|
+
|
|
237
|
+
Experimental. The parser is intentionally conservative and optimized for AI
|
|
238
|
+
HTML streaming, especially full-document artifacts with `<head>`, `<style>`,
|
|
239
|
+
`<body>`, forms, SVG, charts, and layout sections.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ParsedArtifactEnvelope } from "../types/artifact.js";
|
|
2
|
+
/** Strip a leading/trailing markdown code fence if the model wrapped output. */
|
|
3
|
+
export declare function stripOuterFence(input: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Clean common model wrapping around artifact HTML. This only trims code fences
|
|
6
|
+
* at the boundary of the artifact, so literal backticks inside the document are
|
|
7
|
+
* left alone.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cleanArtifactHtml(input: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Final, non-streaming parse of a model envelope. Fail-open: it never throws,
|
|
12
|
+
* and degrades gracefully when tags are missing or malformed. This is the
|
|
13
|
+
* authoritative parser used to produce the final artifact.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseArtifactEnvelope(raw: string): ParsedArtifactEnvelope;
|
|
16
|
+
export type EnvelopeStreamEvent = {
|
|
17
|
+
kind: "message";
|
|
18
|
+
delta: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "artifact_open";
|
|
21
|
+
title: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "artifact";
|
|
24
|
+
delta: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Incremental envelope parser for live streaming. Feed it model-text chunks;
|
|
28
|
+
* it emits message/artifact deltas as they become safe to forward (holding
|
|
29
|
+
* back a small tail so partial delimiters are never emitted as content).
|
|
30
|
+
*
|
|
31
|
+
* The server still re-parses the full output at the end with
|
|
32
|
+
* {@link parseArtifactEnvelope} for the authoritative final artifact, so this
|
|
33
|
+
* parser only needs to be good enough for smooth live updates.
|
|
34
|
+
*/
|
|
35
|
+
export declare class StreamingEnvelopeParser {
|
|
36
|
+
private buf;
|
|
37
|
+
private cursor;
|
|
38
|
+
private state;
|
|
39
|
+
private artifactOpened;
|
|
40
|
+
feed(chunk: string): EnvelopeStreamEvent[];
|
|
41
|
+
flush(): EnvelopeStreamEvent[];
|
|
42
|
+
get hasOpenedArtifact(): boolean;
|
|
43
|
+
private safeEnd;
|
|
44
|
+
private process;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=artifactEnvelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactEnvelope.d.ts","sourceRoot":"","sources":["../../src/artifacts/artifactEnvelope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAcnE,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAOD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,CAoDzE;AAgBD,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AASxC;;;;;;;;GAQG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,cAAc,CAAS;IAE/B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAK1C,KAAK,IAAI,mBAAmB,EAAE;IAI9B,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;CAoFhB"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
const MSG_OPEN = "<assistant_message>";
|
|
2
|
+
const MSG_CLOSE = "</assistant_message>";
|
|
3
|
+
const ART_OPEN = "<html_artifact";
|
|
4
|
+
const ART_CLOSE = "</html_artifact>";
|
|
5
|
+
const GUARD = Math.max(MSG_OPEN.length, MSG_CLOSE.length, ART_OPEN.length, ART_CLOSE.length);
|
|
6
|
+
/** Strip a leading/trailing markdown code fence if the model wrapped output. */
|
|
7
|
+
export function stripOuterFence(input) {
|
|
8
|
+
const trimmed = input.trim();
|
|
9
|
+
const fence = /^```[a-z]*\n([\s\S]*?)\n```$/i.exec(trimmed);
|
|
10
|
+
return fence?.[1] ?? input;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Clean common model wrapping around artifact HTML. This only trims code fences
|
|
14
|
+
* at the boundary of the artifact, so literal backticks inside the document are
|
|
15
|
+
* left alone.
|
|
16
|
+
*/
|
|
17
|
+
export function cleanArtifactHtml(input) {
|
|
18
|
+
let html = input.trim();
|
|
19
|
+
html = html.replace(/^```(?:html)?[ \t]*\r?\n/i, "");
|
|
20
|
+
html = html.replace(/\r?\n```[ \t]*$/i, "");
|
|
21
|
+
return html.trim();
|
|
22
|
+
}
|
|
23
|
+
function parseTitle(openTag) {
|
|
24
|
+
const match = /title\s*=\s*("([^"]*)"|'([^']*)')/i.exec(openTag);
|
|
25
|
+
return (match?.[2] ?? match?.[3] ?? "Untitled artifact").trim();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Final, non-streaming parse of a model envelope. Fail-open: it never throws,
|
|
29
|
+
* and degrades gracefully when tags are missing or malformed. This is the
|
|
30
|
+
* authoritative parser used to produce the final artifact.
|
|
31
|
+
*/
|
|
32
|
+
export function parseArtifactEnvelope(raw) {
|
|
33
|
+
const empty = {
|
|
34
|
+
assistantMessage: "",
|
|
35
|
+
title: "Untitled artifact",
|
|
36
|
+
html: "",
|
|
37
|
+
hasArtifact: false,
|
|
38
|
+
};
|
|
39
|
+
if (typeof raw !== "string" || raw.trim() === "")
|
|
40
|
+
return empty;
|
|
41
|
+
try {
|
|
42
|
+
const source = stripOuterFence(raw);
|
|
43
|
+
const msgMatch = /<assistant_message>([\s\S]*?)<\/assistant_message>/i.exec(source);
|
|
44
|
+
const artMatch = /<html_artifact\b([^>]*)>([\s\S]*?)<\/html_artifact>/i.exec(source);
|
|
45
|
+
if (artMatch) {
|
|
46
|
+
const title = parseTitle(`<html_artifact${artMatch[1] ?? ""}>`);
|
|
47
|
+
const html = cleanArtifactHtml(artMatch[2] ?? "");
|
|
48
|
+
const assistantMessage = (msgMatch?.[1] ?? deriveMessage(source, artMatch.index)).trim();
|
|
49
|
+
return {
|
|
50
|
+
assistantMessage,
|
|
51
|
+
title,
|
|
52
|
+
html,
|
|
53
|
+
hasArtifact: html.length > 0,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// No artifact tag: try to recover a bare HTML document.
|
|
57
|
+
const recovered = recoverBareHtml(source);
|
|
58
|
+
if (recovered) {
|
|
59
|
+
return {
|
|
60
|
+
assistantMessage: (msgMatch?.[1] ?? "Here is the generated artifact.").trim(),
|
|
61
|
+
title: "Untitled artifact",
|
|
62
|
+
html: recovered,
|
|
63
|
+
hasArtifact: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Pure text — treat as the assistant message.
|
|
67
|
+
return {
|
|
68
|
+
assistantMessage: (msgMatch?.[1] ?? source).trim(),
|
|
69
|
+
title: "Untitled artifact",
|
|
70
|
+
html: "",
|
|
71
|
+
hasArtifact: false,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return { ...empty, assistantMessage: raw };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function deriveMessage(source, artifactIndex) {
|
|
79
|
+
const before = source.slice(0, artifactIndex).trim();
|
|
80
|
+
return before || "Here is the generated artifact.";
|
|
81
|
+
}
|
|
82
|
+
function recoverBareHtml(source) {
|
|
83
|
+
const cleaned = cleanArtifactHtml(stripOuterFence(source));
|
|
84
|
+
const doctype = cleaned.search(/<!DOCTYPE html>/i);
|
|
85
|
+
if (doctype !== -1)
|
|
86
|
+
return cleanArtifactHtml(cleaned.slice(doctype));
|
|
87
|
+
const htmlTag = cleaned.search(/<html[\s>]/i);
|
|
88
|
+
if (htmlTag !== -1)
|
|
89
|
+
return cleanArtifactHtml(cleaned.slice(htmlTag));
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Incremental envelope parser for live streaming. Feed it model-text chunks;
|
|
94
|
+
* it emits message/artifact deltas as they become safe to forward (holding
|
|
95
|
+
* back a small tail so partial delimiters are never emitted as content).
|
|
96
|
+
*
|
|
97
|
+
* The server still re-parses the full output at the end with
|
|
98
|
+
* {@link parseArtifactEnvelope} for the authoritative final artifact, so this
|
|
99
|
+
* parser only needs to be good enough for smooth live updates.
|
|
100
|
+
*/
|
|
101
|
+
export class StreamingEnvelopeParser {
|
|
102
|
+
buf = "";
|
|
103
|
+
cursor = 0;
|
|
104
|
+
state = "before_message";
|
|
105
|
+
artifactOpened = false;
|
|
106
|
+
feed(chunk) {
|
|
107
|
+
this.buf += chunk;
|
|
108
|
+
return this.process(false);
|
|
109
|
+
}
|
|
110
|
+
flush() {
|
|
111
|
+
return this.process(true);
|
|
112
|
+
}
|
|
113
|
+
get hasOpenedArtifact() {
|
|
114
|
+
return this.artifactOpened;
|
|
115
|
+
}
|
|
116
|
+
safeEnd(isFinal) {
|
|
117
|
+
return isFinal ? this.buf.length : Math.max(this.cursor, this.buf.length - GUARD);
|
|
118
|
+
}
|
|
119
|
+
process(isFinal) {
|
|
120
|
+
const out = [];
|
|
121
|
+
// Guard against unbounded loops.
|
|
122
|
+
for (let guard = 0; guard < 10_000; guard++) {
|
|
123
|
+
if (this.state === "done")
|
|
124
|
+
break;
|
|
125
|
+
if (this.state === "before_message") {
|
|
126
|
+
const iMsg = this.buf.indexOf(MSG_OPEN, this.cursor);
|
|
127
|
+
const iArt = this.buf.indexOf(ART_OPEN, this.cursor);
|
|
128
|
+
const iBare = findBareHtmlStart(this.buf, this.cursor);
|
|
129
|
+
if (iMsg !== -1 && (iArt === -1 || iMsg < iArt)) {
|
|
130
|
+
this.cursor = iMsg + MSG_OPEN.length;
|
|
131
|
+
this.state = "in_message";
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (iArt !== -1) {
|
|
135
|
+
this.state = "before_artifact";
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (iBare !== -1) {
|
|
139
|
+
const prefix = cleanStreamingPrefix(this.buf.slice(this.cursor, iBare));
|
|
140
|
+
if (prefix)
|
|
141
|
+
out.push({ kind: "message", delta: prefix });
|
|
142
|
+
out.push({ kind: "artifact_open", title: "Untitled artifact" });
|
|
143
|
+
this.artifactOpened = true;
|
|
144
|
+
this.cursor = iBare;
|
|
145
|
+
this.state = "in_artifact";
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
break; // wait for an opener
|
|
149
|
+
}
|
|
150
|
+
if (this.state === "in_message") {
|
|
151
|
+
const iClose = this.buf.indexOf(MSG_CLOSE, this.cursor);
|
|
152
|
+
if (iClose !== -1) {
|
|
153
|
+
if (iClose > this.cursor) {
|
|
154
|
+
out.push({ kind: "message", delta: this.buf.slice(this.cursor, iClose) });
|
|
155
|
+
}
|
|
156
|
+
this.cursor = iClose + MSG_CLOSE.length;
|
|
157
|
+
this.state = "before_artifact";
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const end = this.safeEnd(isFinal);
|
|
161
|
+
if (end > this.cursor) {
|
|
162
|
+
out.push({ kind: "message", delta: this.buf.slice(this.cursor, end) });
|
|
163
|
+
this.cursor = end;
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
if (this.state === "before_artifact") {
|
|
168
|
+
const iArt = this.buf.indexOf(ART_OPEN, this.cursor);
|
|
169
|
+
if (iArt === -1)
|
|
170
|
+
break;
|
|
171
|
+
const iGt = this.buf.indexOf(">", iArt);
|
|
172
|
+
if (iGt === -1)
|
|
173
|
+
break; // wait for full open tag
|
|
174
|
+
const title = parseTitle(this.buf.slice(iArt, iGt + 1));
|
|
175
|
+
out.push({ kind: "artifact_open", title });
|
|
176
|
+
this.artifactOpened = true;
|
|
177
|
+
this.cursor = iGt + 1;
|
|
178
|
+
this.state = "in_artifact";
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (this.state === "in_artifact") {
|
|
182
|
+
const iClose = this.buf.indexOf(ART_CLOSE, this.cursor);
|
|
183
|
+
if (iClose !== -1) {
|
|
184
|
+
if (iClose > this.cursor) {
|
|
185
|
+
out.push({ kind: "artifact", delta: this.buf.slice(this.cursor, iClose) });
|
|
186
|
+
}
|
|
187
|
+
this.cursor = iClose + ART_CLOSE.length;
|
|
188
|
+
this.state = "done";
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const end = this.safeEnd(isFinal);
|
|
192
|
+
if (end > this.cursor) {
|
|
193
|
+
out.push({ kind: "artifact", delta: this.buf.slice(this.cursor, end) });
|
|
194
|
+
this.cursor = end;
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function findBareHtmlStart(input, from) {
|
|
203
|
+
const slice = input.slice(from);
|
|
204
|
+
const doctype = slice.search(/<!DOCTYPE html>/i);
|
|
205
|
+
const html = slice.search(/<html[\s>]/i);
|
|
206
|
+
if (doctype === -1)
|
|
207
|
+
return html === -1 ? -1 : from + html;
|
|
208
|
+
if (html === -1)
|
|
209
|
+
return from + doctype;
|
|
210
|
+
return from + Math.min(doctype, html);
|
|
211
|
+
}
|
|
212
|
+
function cleanStreamingPrefix(input) {
|
|
213
|
+
return input
|
|
214
|
+
.replace(/```(?:html)?[ \t]*\r?\n?/gi, "")
|
|
215
|
+
.trim();
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=artifactEnvelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactEnvelope.js","sourceRoot":"","sources":["../../src/artifacts/artifactEnvelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ArtifactStatus } from "../types/artifact.js";
|
|
2
|
+
export declare const ARTIFACT_STATUS: {
|
|
3
|
+
readonly IDLE: "idle";
|
|
4
|
+
readonly STREAMING: "streaming";
|
|
5
|
+
readonly COMPLETE: "complete";
|
|
6
|
+
readonly ERROR: "error";
|
|
7
|
+
};
|
|
8
|
+
export declare function isTerminalStatus(status: ArtifactStatus): boolean;
|
|
9
|
+
//# sourceMappingURL=artifactStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactStatus.d.ts","sourceRoot":"","sources":["../../src/artifacts/artifactStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,eAAO,MAAM,eAAe;;;;;CAKuB,CAAC;AAEpD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAEhE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const ARTIFACT_STATUS = {
|
|
2
|
+
IDLE: "idle",
|
|
3
|
+
STREAMING: "streaming",
|
|
4
|
+
COMPLETE: "complete",
|
|
5
|
+
ERROR: "error",
|
|
6
|
+
};
|
|
7
|
+
export function isTerminalStatus(status) {
|
|
8
|
+
return status === "complete" || status === "error";
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=artifactStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactStatus.js","sourceRoot":"","sources":["../../src/artifacts/artifactStatus.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;CACmC,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,OAAO,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HtmlArtifact } from "../types/artifact.js";
|
|
2
|
+
/**
|
|
3
|
+
* A tiny in-memory store keyed by artifact id. The client hook uses it to
|
|
4
|
+
* reduce stream events into a stable `Record<id, HtmlArtifact>`.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ArtifactStore {
|
|
7
|
+
private map;
|
|
8
|
+
has(id: string): boolean;
|
|
9
|
+
get(id: string): HtmlArtifact | undefined;
|
|
10
|
+
ensure(id: string, title?: string): HtmlArtifact;
|
|
11
|
+
update(id: string, patch: Partial<Omit<HtmlArtifact, "id" | "type" | "createdAt">>): HtmlArtifact;
|
|
12
|
+
toRecord(): Record<string, HtmlArtifact>;
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=artifactStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactStore.d.ts","sourceRoot":"","sources":["../../src/artifacts/artifactStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAmC;IAE9C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIzC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY;IAQhD,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC,GAC9D,YAAY;IAOf,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IAIxC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createHtmlArtifact, updateHtmlArtifact } from "./htmlArtifact.js";
|
|
2
|
+
/**
|
|
3
|
+
* A tiny in-memory store keyed by artifact id. The client hook uses it to
|
|
4
|
+
* reduce stream events into a stable `Record<id, HtmlArtifact>`.
|
|
5
|
+
*/
|
|
6
|
+
export class ArtifactStore {
|
|
7
|
+
map = new Map();
|
|
8
|
+
has(id) {
|
|
9
|
+
return this.map.has(id);
|
|
10
|
+
}
|
|
11
|
+
get(id) {
|
|
12
|
+
return this.map.get(id);
|
|
13
|
+
}
|
|
14
|
+
ensure(id, title) {
|
|
15
|
+
const existing = this.map.get(id);
|
|
16
|
+
if (existing)
|
|
17
|
+
return existing;
|
|
18
|
+
const created = createHtmlArtifact({ id, title });
|
|
19
|
+
this.map.set(id, created);
|
|
20
|
+
return created;
|
|
21
|
+
}
|
|
22
|
+
update(id, patch) {
|
|
23
|
+
const current = this.ensure(id);
|
|
24
|
+
const next = updateHtmlArtifact(current, patch);
|
|
25
|
+
this.map.set(id, next);
|
|
26
|
+
return next;
|
|
27
|
+
}
|
|
28
|
+
toRecord() {
|
|
29
|
+
return Object.fromEntries(this.map);
|
|
30
|
+
}
|
|
31
|
+
clear() {
|
|
32
|
+
this.map.clear();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=artifactStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifactStore.js","sourceRoot":"","sources":["../../src/artifacts/artifactStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG3E;;;GAGG;AACH,MAAM,OAAO,aAAa;IAChB,GAAG,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE9C,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,KAAc;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,CACJ,EAAU,EACV,KAA+D;QAE/D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;QACN,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HtmlArtifact, ArtifactStatus } from "../types/artifact.js";
|
|
2
|
+
/** Create a fresh artifact record in the `streaming` state. */
|
|
3
|
+
export declare function createHtmlArtifact(params: {
|
|
4
|
+
id: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
status?: ArtifactStatus;
|
|
7
|
+
}): HtmlArtifact;
|
|
8
|
+
/** Immutably apply a partial update, refreshing `updatedAt`. */
|
|
9
|
+
export declare function updateHtmlArtifact(artifact: HtmlArtifact, patch: Partial<Omit<HtmlArtifact, "id" | "type" | "createdAt">>): HtmlArtifact;
|
|
10
|
+
//# sourceMappingURL=htmlArtifact.d.ts.map
|