glirastes 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +154 -9
- package/codegen/package.json +5 -0
- package/dist/cjs/codegen/asset-sync.d.ts +20 -0
- package/dist/cjs/codegen/asset-sync.js +28 -0
- package/dist/cjs/codegen/coverage.d.ts +66 -0
- package/dist/cjs/codegen/coverage.js +408 -0
- package/dist/cjs/codegen/endpoint-scanner.d.ts +16 -0
- package/dist/cjs/codegen/endpoint-scanner.js +197 -0
- package/dist/cjs/codegen/format.d.ts +17 -0
- package/dist/cjs/codegen/format.js +34 -0
- package/dist/cjs/codegen/fs-utils.d.ts +45 -0
- package/dist/cjs/codegen/fs-utils.js +165 -0
- package/dist/cjs/codegen/index.d.ts +13 -0
- package/dist/cjs/codegen/index.js +33 -0
- package/dist/cjs/codegen/mcp-generator.d.ts +50 -0
- package/dist/cjs/codegen/mcp-generator.js +803 -0
- package/dist/cjs/codegen/module-generator.d.ts +11 -0
- package/dist/cjs/codegen/module-generator.js +353 -0
- package/dist/cjs/codegen/nestjs-scanner.d.ts +43 -0
- package/dist/cjs/codegen/nestjs-scanner.js +241 -0
- package/dist/cjs/codegen/output-recommender.d.ts +23 -0
- package/dist/cjs/codegen/output-recommender.js +33 -0
- package/dist/cjs/codegen/scaffolder.d.ts +36 -0
- package/dist/cjs/codegen/scaffolder.js +262 -0
- package/dist/cjs/codegen/skill-generator.d.ts +49 -0
- package/dist/cjs/codegen/skill-generator.js +967 -0
- package/dist/cjs/codegen/types.d.ts +52 -0
- package/dist/cjs/codegen/types.js +16 -0
- package/dist/cjs/codegen/ui-scanner.d.ts +24 -0
- package/dist/cjs/codegen/ui-scanner.js +202 -0
- package/dist/cjs/codegen/validator.d.ts +35 -0
- package/dist/cjs/codegen/validator.js +292 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/openapi/index.d.ts +78 -0
- package/dist/cjs/openapi/index.js +347 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/react/audio-worklet-processor.d.ts +16 -0
- package/dist/cjs/react/audio-worklet-processor.js +27 -0
- package/dist/cjs/react/bridges/rest-session-bridge.d.ts +113 -0
- package/dist/cjs/react/bridges/rest-session-bridge.js +209 -0
- package/dist/cjs/react/components/ai-chat-panel.d.ts +12 -0
- package/dist/cjs/react/components/ai-chat-panel.js +67 -0
- package/dist/cjs/react/components/ai-trigger-button.d.ts +2 -0
- package/dist/cjs/react/components/ai-trigger-button.js +239 -0
- package/dist/cjs/react/components/approval-card.d.ts +9 -0
- package/dist/cjs/react/components/approval-card.js +24 -0
- package/dist/cjs/react/components/bulk-approval-card.d.ts +9 -0
- package/dist/cjs/react/components/bulk-approval-card.js +36 -0
- package/dist/cjs/react/components/chat-input.d.ts +10 -0
- package/dist/cjs/react/components/chat-input.js +60 -0
- package/dist/cjs/react/components/chat-window.d.ts +2 -0
- package/dist/cjs/react/components/chat-window.js +134 -0
- package/dist/cjs/react/components/confirm-dialog.d.ts +32 -0
- package/dist/cjs/react/components/confirm-dialog.js +48 -0
- package/dist/cjs/react/components/floating-chat-ui.d.ts +90 -0
- package/dist/cjs/react/components/floating-chat-ui.js +163 -0
- package/dist/cjs/react/components/mention-chip.d.ts +16 -0
- package/dist/cjs/react/components/mention-chip.js +42 -0
- package/dist/cjs/react/components/mention-input.d.ts +8 -0
- package/dist/cjs/react/components/mention-input.js +117 -0
- package/dist/cjs/react/components/message-bubble.d.ts +11 -0
- package/dist/cjs/react/components/message-bubble.js +171 -0
- package/dist/cjs/react/components/message-list.d.ts +8 -0
- package/dist/cjs/react/components/message-list.js +52 -0
- package/dist/cjs/react/components/pipeline-timeline.d.ts +7 -0
- package/dist/cjs/react/components/pipeline-timeline.js +72 -0
- package/dist/cjs/react/components/recording-bar.d.ts +2 -0
- package/dist/cjs/react/components/recording-bar.js +81 -0
- package/dist/cjs/react/components/recording-controls.d.ts +18 -0
- package/dist/cjs/react/components/recording-controls.js +38 -0
- package/dist/cjs/react/components/rich-mention-input.d.ts +2 -0
- package/dist/cjs/react/components/rich-mention-input.js +571 -0
- package/dist/cjs/react/components/session-switcher.d.ts +14 -0
- package/dist/cjs/react/components/session-switcher.js +133 -0
- package/dist/cjs/react/components/suggestion-bar.d.ts +9 -0
- package/dist/cjs/react/components/suggestion-bar.js +47 -0
- package/dist/cjs/react/components/suggestion-chip.d.ts +9 -0
- package/dist/cjs/react/components/suggestion-chip.js +14 -0
- package/dist/cjs/react/components/voice-input-addon.d.ts +13 -0
- package/dist/cjs/react/components/voice-input-addon.js +31 -0
- package/dist/cjs/react/components/voice-input-button.d.ts +2 -0
- package/dist/cjs/react/components/voice-input-button.js +55 -0
- package/dist/cjs/react/components/wavesurfer-loader.d.ts +5 -0
- package/dist/cjs/react/components/wavesurfer-loader.js +36 -0
- package/dist/cjs/react/hooks/use-ai-chat.d.ts +22 -0
- package/dist/cjs/react/hooks/use-ai-chat.js +51 -0
- package/dist/cjs/react/hooks/use-approvals.d.ts +23 -0
- package/dist/cjs/react/hooks/use-approvals.js +63 -0
- package/dist/cjs/react/hooks/use-deepgram-transcription.d.ts +2 -0
- package/dist/cjs/react/hooks/use-deepgram-transcription.js +329 -0
- package/dist/cjs/react/hooks/use-drag-resize-panel.d.ts +48 -0
- package/dist/cjs/react/hooks/use-drag-resize-panel.js +308 -0
- package/dist/cjs/react/hooks/use-draggable-position.d.ts +25 -0
- package/dist/cjs/react/hooks/use-draggable-position.js +134 -0
- package/dist/cjs/react/hooks/use-keyboard-shortcut.d.ts +20 -0
- package/dist/cjs/react/hooks/use-keyboard-shortcut.js +93 -0
- package/dist/cjs/react/hooks/use-mentions.d.ts +23 -0
- package/dist/cjs/react/hooks/use-mentions.js +42 -0
- package/dist/cjs/react/hooks/use-suggestions.d.ts +22 -0
- package/dist/cjs/react/hooks/use-suggestions.js +39 -0
- package/dist/cjs/react/index.d.ts +43 -0
- package/dist/cjs/react/index.js +111 -0
- package/dist/cjs/react/provider/ai-chat-provider.d.ts +45 -0
- package/dist/cjs/react/provider/ai-chat-provider.js +1024 -0
- package/dist/cjs/react/provider/chat-context.d.ts +84 -0
- package/dist/cjs/react/provider/chat-context.js +13 -0
- package/dist/cjs/react/template.d.ts +84 -0
- package/dist/cjs/react/template.js +90 -0
- package/dist/cjs/react/themes.d.ts +24 -0
- package/dist/cjs/react/themes.js +273 -0
- package/dist/cjs/react/transports/langgraph/index.d.ts +2 -0
- package/dist/cjs/react/transports/langgraph/index.js +8 -0
- package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.d.ts +62 -0
- package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.js +94 -0
- package/dist/cjs/react/transports/langgraph.d.ts +71 -0
- package/dist/cjs/react/transports/langgraph.js +369 -0
- package/dist/cjs/react/transports/vercel/index.d.ts +2 -0
- package/dist/cjs/react/transports/vercel/index.js +8 -0
- package/dist/cjs/react/transports/vercel/vercel-ai-chat.d.ts +49 -0
- package/dist/cjs/react/transports/vercel/vercel-ai-chat.js +81 -0
- package/dist/cjs/react/transports/vercel.d.ts +30 -0
- package/dist/cjs/react/transports/vercel.js +69 -0
- package/dist/cjs/react/types.d.ts +760 -0
- package/dist/cjs/react/types.js +2 -0
- package/dist/cjs/react/ui.d.ts +73 -0
- package/dist/cjs/react/ui.js +183 -0
- package/dist/cjs/react/utils/create-approval-description.d.ts +53 -0
- package/dist/cjs/react/utils/create-approval-description.js +122 -0
- package/dist/cjs/react/utils/create-tool-result-handler.d.ts +90 -0
- package/dist/cjs/react/utils/create-tool-result-handler.js +168 -0
- package/dist/cjs/react/utils/mention-markup.d.ts +13 -0
- package/dist/cjs/react/utils/mention-markup.js +117 -0
- package/dist/cjs/react/utils/merge-pipeline-steps.d.ts +19 -0
- package/dist/cjs/react/utils/merge-pipeline-steps.js +81 -0
- package/dist/cjs/react/utils/sanitize-stored-messages.d.ts +23 -0
- package/dist/cjs/react/utils/sanitize-stored-messages.js +52 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.d.ts +10 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.js +42 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.d.ts +32 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.js +4 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.d.ts +11 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.js +80 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.d.ts +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.js +119 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.d.ts +13 -0
- package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.js +131 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.d.ts +7 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.js +52 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.d.ts +19 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.js +108 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.d.ts +8 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.js +59 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/index.d.ts +3 -0
- package/dist/cjs/server/adapters/nestjs/chat/dto/index.js +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/index.d.ts +3 -0
- package/dist/cjs/server/adapters/nestjs/chat/index.js +9 -0
- package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +4 -0
- package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.js +73 -0
- package/dist/cjs/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
- package/dist/cjs/server/adapters/nestjs/chat/ws-loader.js +72 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.d.ts +6 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.js +13 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.d.ts +5 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.js +15 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.d.ts +6 -0
- package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.js +22 -0
- package/dist/cjs/server/adapters/nestjs/decorators/constants.d.ts +4 -0
- package/dist/cjs/server/adapters/nestjs/decorators/constants.js +7 -0
- package/dist/cjs/server/adapters/nestjs/index.d.ts +14 -0
- package/dist/cjs/server/adapters/nestjs/index.js +42 -0
- package/dist/cjs/server/adapters/nestjs/metadata.d.ts +39 -0
- package/dist/cjs/server/adapters/nestjs/metadata.js +36 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.d.ts +36 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.js +159 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.d.ts +37 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.js +44 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.d.ts +28 -0
- package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.js +41 -0
- package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.d.ts +16 -0
- package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.js +117 -0
- package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.d.ts +26 -0
- package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.js +259 -0
- package/dist/cjs/server/adapters/nestjs/swagger.d.ts +7 -0
- package/dist/cjs/server/adapters/nestjs/swagger.js +39 -0
- package/dist/cjs/server/adapters/nextjs/context-helpers.d.ts +22 -0
- package/dist/cjs/server/adapters/nextjs/context-helpers.js +60 -0
- package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.d.ts +94 -0
- package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.js +965 -0
- package/dist/cjs/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
- package/dist/cjs/server/adapters/nextjs/filter-fallback-error.js +41 -0
- package/dist/cjs/server/adapters/nextjs/index.d.ts +8 -0
- package/dist/cjs/server/adapters/nextjs/index.js +22 -0
- package/dist/cjs/server/adapters/nextjs/prepare-model-messages.d.ts +58 -0
- package/dist/cjs/server/adapters/nextjs/prepare-model-messages.js +114 -0
- package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.d.ts +64 -0
- package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.js +489 -0
- package/dist/cjs/server/adapters/nextjs/server-action-helper.d.ts +7 -0
- package/dist/cjs/server/adapters/nextjs/server-action-helper.js +40 -0
- package/dist/cjs/server/adapters/nextjs/types.d.ts +246 -0
- package/dist/cjs/server/adapters/nextjs/types.js +2 -0
- package/dist/cjs/server/adapters/nextjs/with-ai-tool.d.ts +9 -0
- package/dist/cjs/server/adapters/nextjs/with-ai-tool.js +12 -0
- package/dist/cjs/server/core/followup-tool.d.ts +9 -0
- package/dist/cjs/server/core/followup-tool.js +82 -0
- package/dist/cjs/server/core/index.d.ts +139 -0
- package/dist/cjs/server/core/index.js +818 -0
- package/dist/cjs/server/core/intent-classifier.d.ts +94 -0
- package/dist/cjs/server/core/intent-classifier.js +324 -0
- package/dist/cjs/server/core/model-selector.d.ts +12 -0
- package/dist/cjs/server/core/model-selector.js +48 -0
- package/dist/cjs/server/core/module-router.d.ts +14 -0
- package/dist/cjs/server/core/module-router.js +110 -0
- package/dist/cjs/server/core/zod-compact.d.ts +18 -0
- package/dist/cjs/server/core/zod-compact.js +129 -0
- package/dist/cjs/server/index.d.ts +6 -0
- package/dist/cjs/server/index.js +28 -0
- package/dist/cjs/server/lancer/cache.d.ts +9 -0
- package/dist/cjs/server/lancer/cache.js +33 -0
- package/dist/cjs/server/lancer/client.d.ts +2 -0
- package/dist/cjs/server/lancer/client.js +279 -0
- package/dist/cjs/server/lancer/errors.d.ts +13 -0
- package/dist/cjs/server/lancer/errors.js +21 -0
- package/dist/cjs/server/lancer/index.d.ts +3 -0
- package/dist/cjs/server/lancer/index.js +7 -0
- package/dist/cjs/server/lancer/telemetry-buffer.d.ts +15 -0
- package/dist/cjs/server/lancer/telemetry-buffer.js +64 -0
- package/dist/cjs/server/lancer/types.d.ts +201 -0
- package/dist/cjs/server/lancer/types.js +5 -0
- package/dist/cjs/server/pii-shield/aegis-detector.d.ts +26 -0
- package/dist/cjs/server/pii-shield/aegis-detector.js +26 -0
- package/dist/cjs/server/pii-shield/create-pii-shield.d.ts +2 -0
- package/dist/cjs/server/pii-shield/create-pii-shield.js +191 -0
- package/dist/cjs/server/pii-shield/deep-walk.d.ts +1 -0
- package/dist/cjs/server/pii-shield/deep-walk.js +19 -0
- package/dist/cjs/server/pii-shield/fake-data.d.ts +5 -0
- package/dist/cjs/server/pii-shield/fake-data.js +170 -0
- package/dist/cjs/server/pii-shield/index.d.ts +4 -0
- package/dist/cjs/server/pii-shield/index.js +9 -0
- package/dist/cjs/server/pii-shield/leakage.d.ts +1 -0
- package/dist/cjs/server/pii-shield/leakage.js +15 -0
- package/dist/cjs/server/pii-shield/session-mapping.d.ts +12 -0
- package/dist/cjs/server/pii-shield/session-mapping.js +70 -0
- package/dist/cjs/server/pipeline.d.ts +26 -0
- package/dist/cjs/server/pipeline.js +127 -0
- package/dist/cjs/server/testing/approvals.d.ts +11 -0
- package/dist/cjs/server/testing/approvals.js +41 -0
- package/dist/cjs/server/testing/combination.d.ts +3 -0
- package/dist/cjs/server/testing/combination.js +83 -0
- package/dist/cjs/server/testing/create-test-suite.d.ts +29 -0
- package/dist/cjs/server/testing/create-test-suite.js +81 -0
- package/dist/cjs/server/testing/edge-cases.d.ts +8 -0
- package/dist/cjs/server/testing/edge-cases.js +277 -0
- package/dist/cjs/server/testing/guardrails.d.ts +14 -0
- package/dist/cjs/server/testing/guardrails.js +152 -0
- package/dist/cjs/server/testing/helpers.d.ts +14 -0
- package/dist/cjs/server/testing/helpers.js +119 -0
- package/dist/cjs/server/testing/index.d.ts +12 -0
- package/dist/cjs/server/testing/index.js +37 -0
- package/dist/cjs/server/testing/mock-executor.d.ts +8 -0
- package/dist/cjs/server/testing/mock-executor.js +40 -0
- package/dist/cjs/server/testing/regression.d.ts +7 -0
- package/dist/cjs/server/testing/regression.js +27 -0
- package/dist/cjs/server/testing/routing.d.ts +12 -0
- package/dist/cjs/server/testing/routing.js +63 -0
- package/dist/cjs/server/testing/schema-consistency.d.ts +6 -0
- package/dist/cjs/server/testing/schema-consistency.js +56 -0
- package/dist/cjs/server/testing/smoke.d.ts +11 -0
- package/dist/cjs/server/testing/smoke.js +64 -0
- package/dist/cjs/server/testing/types.d.ts +156 -0
- package/dist/cjs/server/testing/types.js +2 -0
- package/dist/cjs/types.d.ts +696 -0
- package/dist/cjs/types.js +91 -0
- package/dist/cli/commands/install-skills.d.ts +17 -0
- package/dist/cli/commands/install-skills.js +185 -0
- package/dist/cli/commands/install-skills.js.map +1 -0
- package/dist/cli/index.js +25 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/react/components/ai-trigger-button.js +4 -6
- package/dist/react/components/ai-trigger-button.js.map +1 -1
- package/dist/react/components/recording-bar.js +4 -6
- package/dist/react/components/recording-bar.js.map +1 -1
- package/dist/react/components/wavesurfer-loader.d.ts +5 -0
- package/dist/react/components/wavesurfer-loader.js +34 -0
- package/dist/react/components/wavesurfer-loader.js.map +1 -0
- package/dist/server/adapters/nestjs/chat/ai-chat.module.d.ts +1 -1
- package/dist/server/adapters/nestjs/chat/ai-chat.module.js +3 -2
- package/dist/server/adapters/nestjs/chat/ai-chat.module.js.map +1 -1
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +1 -1
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js +10 -8
- package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js.map +1 -1
- package/dist/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
- package/dist/server/adapters/nestjs/chat/ws-loader.js +37 -0
- package/dist/server/adapters/nestjs/chat/ws-loader.js.map +1 -0
- package/openapi/package.json +5 -0
- package/package.json +59 -16
- package/react/langgraph/package.json +5 -0
- package/react/package.json +5 -0
- package/react/vercel/package.json +5 -0
- package/server/nestjs/package.json +5 -0
- package/server/nextjs/package.json +5 -0
- package/server/package.json +5 -0
- package/server/testing/package.json +5 -0
- package/skills/README.md +107 -0
- package/skills/building-glirastes-chat-ui/SKILL.md +378 -0
- package/skills/integrating-glirastes-nestjs/SKILL.md +346 -0
- package/skills/integrating-glirastes-nextjs/SKILL.md +312 -0
- package/skills/integrating-glirastes-nextjs-with-nestjs-backend/SKILL.md +359 -0
- package/skills/maintaining-glirastes-tools/SKILL.md +467 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { EndpointMethod, OpenApiAiExtension } from '../types.js';
|
|
2
|
+
type ParameterLocation = 'path' | 'query' | 'header' | 'cookie';
|
|
3
|
+
interface OpenApiReference {
|
|
4
|
+
$ref: string;
|
|
5
|
+
}
|
|
6
|
+
interface OpenApiSchema {
|
|
7
|
+
type?: string;
|
|
8
|
+
format?: string;
|
|
9
|
+
enum?: unknown[];
|
|
10
|
+
items?: OpenApiSchema | OpenApiReference;
|
|
11
|
+
properties?: Record<string, OpenApiSchema | OpenApiReference>;
|
|
12
|
+
required?: string[];
|
|
13
|
+
additionalProperties?: boolean | OpenApiSchema | OpenApiReference;
|
|
14
|
+
}
|
|
15
|
+
interface OpenApiMediaType {
|
|
16
|
+
schema?: OpenApiSchema | OpenApiReference;
|
|
17
|
+
}
|
|
18
|
+
interface OpenApiRequestBody {
|
|
19
|
+
required?: boolean;
|
|
20
|
+
content?: Record<string, OpenApiMediaType>;
|
|
21
|
+
}
|
|
22
|
+
interface OpenApiParameter {
|
|
23
|
+
name: string;
|
|
24
|
+
in: ParameterLocation;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
schema?: OpenApiSchema | OpenApiReference;
|
|
27
|
+
}
|
|
28
|
+
interface OpenApiOperation {
|
|
29
|
+
operationId?: string;
|
|
30
|
+
summary?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
parameters?: Array<OpenApiParameter | OpenApiReference>;
|
|
33
|
+
requestBody?: OpenApiRequestBody | OpenApiReference;
|
|
34
|
+
'x-ai'?: OpenApiAiExtension;
|
|
35
|
+
}
|
|
36
|
+
interface OpenApiPathItem {
|
|
37
|
+
parameters?: Array<OpenApiParameter | OpenApiReference>;
|
|
38
|
+
get?: OpenApiOperation;
|
|
39
|
+
post?: OpenApiOperation;
|
|
40
|
+
patch?: OpenApiOperation;
|
|
41
|
+
put?: OpenApiOperation;
|
|
42
|
+
delete?: OpenApiOperation;
|
|
43
|
+
}
|
|
44
|
+
interface OpenApiComponents {
|
|
45
|
+
schemas?: Record<string, OpenApiSchema>;
|
|
46
|
+
parameters?: Record<string, OpenApiParameter>;
|
|
47
|
+
requestBodies?: Record<string, OpenApiRequestBody>;
|
|
48
|
+
}
|
|
49
|
+
interface OpenApiDocument {
|
|
50
|
+
paths?: Record<string, OpenApiPathItem>;
|
|
51
|
+
components?: OpenApiComponents;
|
|
52
|
+
}
|
|
53
|
+
interface ValidationResult {
|
|
54
|
+
enabledTools: number;
|
|
55
|
+
errors: string[];
|
|
56
|
+
warnings: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface GeneratedToolSpec {
|
|
59
|
+
id: string;
|
|
60
|
+
toolName: string;
|
|
61
|
+
description: string;
|
|
62
|
+
method: EndpointMethod;
|
|
63
|
+
path: string;
|
|
64
|
+
needsApproval: boolean;
|
|
65
|
+
inputSchemaCode: string;
|
|
66
|
+
uiActionOnSuccess?: Record<string, unknown> | Record<string, unknown>[];
|
|
67
|
+
}
|
|
68
|
+
export declare function validateOpenApiDocument(document: OpenApiDocument): ValidationResult;
|
|
69
|
+
export declare function extractGeneratedToolSpecs(document: OpenApiDocument): GeneratedToolSpec[];
|
|
70
|
+
export declare function renderTypeScriptFromSpecs(specs: GeneratedToolSpec[]): string;
|
|
71
|
+
export declare function validateOpenApiFile(options: {
|
|
72
|
+
inputPath: string;
|
|
73
|
+
}): Promise<ValidationResult>;
|
|
74
|
+
export declare function generateFromOpenApiFile(options: {
|
|
75
|
+
inputPath: string;
|
|
76
|
+
outputPath: string;
|
|
77
|
+
}): Promise<ValidationResult>;
|
|
78
|
+
export {};
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateOpenApiDocument = validateOpenApiDocument;
|
|
4
|
+
exports.extractGeneratedToolSpecs = extractGeneratedToolSpecs;
|
|
5
|
+
exports.renderTypeScriptFromSpecs = renderTypeScriptFromSpecs;
|
|
6
|
+
exports.validateOpenApiFile = validateOpenApiFile;
|
|
7
|
+
exports.generateFromOpenApiFile = generateFromOpenApiFile;
|
|
8
|
+
const promises_1 = require("node:fs/promises");
|
|
9
|
+
const SUPPORTED_METHODS = ['get', 'post', 'patch', 'put', 'delete'];
|
|
10
|
+
const MUTATING_METHODS = new Set(['post', 'patch', 'put', 'delete']);
|
|
11
|
+
function isRef(value) {
|
|
12
|
+
return typeof value === 'object' && value !== null && '$ref' in value;
|
|
13
|
+
}
|
|
14
|
+
function toMethod(value) {
|
|
15
|
+
return value.toUpperCase();
|
|
16
|
+
}
|
|
17
|
+
function normalizePath(path) {
|
|
18
|
+
return path.replace(/\{([^}]+)\}/g, ':$1');
|
|
19
|
+
}
|
|
20
|
+
function normalizeToolName(value) {
|
|
21
|
+
return value.trim();
|
|
22
|
+
}
|
|
23
|
+
function escapeString(value) {
|
|
24
|
+
return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
25
|
+
}
|
|
26
|
+
function renderObject(value, indent = 2) {
|
|
27
|
+
return JSON.stringify(value, null, indent);
|
|
28
|
+
}
|
|
29
|
+
function renderObjectKey(key) {
|
|
30
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : `'${escapeString(key)}'`;
|
|
31
|
+
}
|
|
32
|
+
function readRef(document, ref) {
|
|
33
|
+
if (!ref.startsWith('#/')) {
|
|
34
|
+
throw new Error(`Only local refs are supported in this prototype: ${ref}`);
|
|
35
|
+
}
|
|
36
|
+
const segments = ref.slice(2).split('/');
|
|
37
|
+
let current = document;
|
|
38
|
+
for (const rawSegment of segments) {
|
|
39
|
+
const segment = rawSegment.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
40
|
+
if (typeof current !== 'object' || current === null || !(segment in current)) {
|
|
41
|
+
throw new Error(`Cannot resolve ref: ${ref}`);
|
|
42
|
+
}
|
|
43
|
+
current = current[segment];
|
|
44
|
+
}
|
|
45
|
+
return current;
|
|
46
|
+
}
|
|
47
|
+
function resolveSchema(document, schema, seenRefs = new Set()) {
|
|
48
|
+
if (!schema)
|
|
49
|
+
return undefined;
|
|
50
|
+
if (!isRef(schema))
|
|
51
|
+
return schema;
|
|
52
|
+
const ref = schema.$ref;
|
|
53
|
+
if (seenRefs.has(ref)) {
|
|
54
|
+
return { type: 'object' };
|
|
55
|
+
}
|
|
56
|
+
seenRefs.add(ref);
|
|
57
|
+
const resolved = readRef(document, ref);
|
|
58
|
+
if (typeof resolved !== 'object' || resolved === null) {
|
|
59
|
+
throw new Error(`Ref does not point to an object schema: ${ref}`);
|
|
60
|
+
}
|
|
61
|
+
return resolveSchema(document, resolved, seenRefs);
|
|
62
|
+
}
|
|
63
|
+
function resolveParameter(document, parameter) {
|
|
64
|
+
if (!isRef(parameter))
|
|
65
|
+
return parameter;
|
|
66
|
+
const resolved = readRef(document, parameter.$ref);
|
|
67
|
+
if (!resolved || typeof resolved !== 'object') {
|
|
68
|
+
throw new Error(`Invalid parameter ref: ${parameter.$ref}`);
|
|
69
|
+
}
|
|
70
|
+
return resolved;
|
|
71
|
+
}
|
|
72
|
+
function resolveRequestBody(document, requestBody) {
|
|
73
|
+
if (!requestBody)
|
|
74
|
+
return undefined;
|
|
75
|
+
if (!isRef(requestBody))
|
|
76
|
+
return requestBody;
|
|
77
|
+
const resolved = readRef(document, requestBody.$ref);
|
|
78
|
+
if (!resolved || typeof resolved !== 'object') {
|
|
79
|
+
throw new Error(`Invalid requestBody ref: ${requestBody.$ref}`);
|
|
80
|
+
}
|
|
81
|
+
return resolved;
|
|
82
|
+
}
|
|
83
|
+
function collectOperations(document) {
|
|
84
|
+
const operations = [];
|
|
85
|
+
for (const [path, pathItem] of Object.entries(document.paths ?? {})) {
|
|
86
|
+
for (const method of SUPPORTED_METHODS) {
|
|
87
|
+
const operation = pathItem[method];
|
|
88
|
+
if (!operation)
|
|
89
|
+
continue;
|
|
90
|
+
operations.push({ path, method, operation, pathItem });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return operations;
|
|
94
|
+
}
|
|
95
|
+
function getMergedParameters(document, context) {
|
|
96
|
+
const merged = new Map();
|
|
97
|
+
const pathLevel = context.pathItem.parameters ?? [];
|
|
98
|
+
const operationLevel = context.operation.parameters ?? [];
|
|
99
|
+
for (const param of pathLevel) {
|
|
100
|
+
const resolved = resolveParameter(document, param);
|
|
101
|
+
merged.set(`${resolved.in}:${resolved.name}`, resolved);
|
|
102
|
+
}
|
|
103
|
+
for (const param of operationLevel) {
|
|
104
|
+
const resolved = resolveParameter(document, param);
|
|
105
|
+
merged.set(`${resolved.in}:${resolved.name}`, resolved);
|
|
106
|
+
}
|
|
107
|
+
return Array.from(merged.values());
|
|
108
|
+
}
|
|
109
|
+
function listPathParams(path) {
|
|
110
|
+
return Array.from(path.matchAll(/\{([^}]+)\}/g), (match) => match[1]);
|
|
111
|
+
}
|
|
112
|
+
function isNonEmptyStringArray(value) {
|
|
113
|
+
return Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === 'string' && item.trim());
|
|
114
|
+
}
|
|
115
|
+
function schemaToZodCode(document, schema) {
|
|
116
|
+
const resolved = resolveSchema(document, schema);
|
|
117
|
+
if (!resolved)
|
|
118
|
+
return 'z.unknown()';
|
|
119
|
+
if (Array.isArray(resolved.enum) && resolved.enum.length > 0) {
|
|
120
|
+
if (resolved.enum.every((item) => typeof item === 'string')) {
|
|
121
|
+
return `z.enum(${renderObject(resolved.enum)})`;
|
|
122
|
+
}
|
|
123
|
+
const literals = resolved.enum
|
|
124
|
+
.filter((item) => ['string', 'number', 'boolean'].includes(typeof item))
|
|
125
|
+
.map((item) => `z.literal(${JSON.stringify(item)})`);
|
|
126
|
+
if (literals.length > 0) {
|
|
127
|
+
return `z.union([${literals.join(', ')}])`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (resolved.type === 'string') {
|
|
131
|
+
if (resolved.format === 'uuid')
|
|
132
|
+
return 'z.string().uuid()';
|
|
133
|
+
return 'z.string()';
|
|
134
|
+
}
|
|
135
|
+
if (resolved.type === 'integer' || resolved.type === 'number') {
|
|
136
|
+
return 'z.number()';
|
|
137
|
+
}
|
|
138
|
+
if (resolved.type === 'boolean') {
|
|
139
|
+
return 'z.boolean()';
|
|
140
|
+
}
|
|
141
|
+
if (resolved.type === 'array') {
|
|
142
|
+
return `z.array(${schemaToZodCode(document, resolved.items)})`;
|
|
143
|
+
}
|
|
144
|
+
if (resolved.type === 'object' || resolved.properties || resolved.additionalProperties) {
|
|
145
|
+
const properties = resolved.properties ?? {};
|
|
146
|
+
const required = new Set(resolved.required ?? []);
|
|
147
|
+
const entries = Object.entries(properties).map(([name, childSchema]) => {
|
|
148
|
+
const base = schemaToZodCode(document, childSchema);
|
|
149
|
+
const code = required.has(name) ? base : `${base}.optional()`;
|
|
150
|
+
return `${renderObjectKey(name)}: ${code}`;
|
|
151
|
+
});
|
|
152
|
+
const objectCode = `z.object({${entries.length > 0 ? `\n ${entries.join(',\n ')}\n ` : ''}})`;
|
|
153
|
+
if (resolved.additionalProperties) {
|
|
154
|
+
return `${objectCode}.passthrough()`;
|
|
155
|
+
}
|
|
156
|
+
return objectCode;
|
|
157
|
+
}
|
|
158
|
+
return 'z.unknown()';
|
|
159
|
+
}
|
|
160
|
+
function addOrMergeField(fields, candidate) {
|
|
161
|
+
const existing = fields.get(candidate.name);
|
|
162
|
+
if (!existing) {
|
|
163
|
+
fields.set(candidate.name, candidate);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const mergedRequired = existing.required || candidate.required;
|
|
167
|
+
const mergedCode = existing.zodCode === candidate.zodCode ? existing.zodCode : 'z.unknown()';
|
|
168
|
+
fields.set(candidate.name, {
|
|
169
|
+
...existing,
|
|
170
|
+
required: mergedRequired,
|
|
171
|
+
zodCode: mergedCode,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function createInputSchemaCode(document, context) {
|
|
175
|
+
const fields = new Map();
|
|
176
|
+
const mergedParameters = getMergedParameters(document, context);
|
|
177
|
+
for (const parameter of mergedParameters) {
|
|
178
|
+
const required = parameter.in === 'path' ? true : Boolean(parameter.required);
|
|
179
|
+
addOrMergeField(fields, {
|
|
180
|
+
name: parameter.name,
|
|
181
|
+
zodCode: schemaToZodCode(document, parameter.schema),
|
|
182
|
+
required,
|
|
183
|
+
source: parameter.in,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const requestBody = resolveRequestBody(document, context.operation.requestBody);
|
|
187
|
+
const jsonSchema = requestBody?.content?.['application/json']?.schema;
|
|
188
|
+
const resolvedBodySchema = resolveSchema(document, jsonSchema);
|
|
189
|
+
if (resolvedBodySchema) {
|
|
190
|
+
if (resolvedBodySchema.type === 'object' || resolvedBodySchema.properties) {
|
|
191
|
+
const required = new Set(resolvedBodySchema.required ?? []);
|
|
192
|
+
for (const [name, child] of Object.entries(resolvedBodySchema.properties ?? {})) {
|
|
193
|
+
addOrMergeField(fields, {
|
|
194
|
+
name,
|
|
195
|
+
zodCode: schemaToZodCode(document, child),
|
|
196
|
+
required: required.has(name),
|
|
197
|
+
source: 'body',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
addOrMergeField(fields, {
|
|
203
|
+
name: 'body',
|
|
204
|
+
zodCode: schemaToZodCode(document, resolvedBodySchema),
|
|
205
|
+
required: Boolean(requestBody?.required),
|
|
206
|
+
source: 'body',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const sorted = Array.from(fields.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
211
|
+
if (sorted.length === 0) {
|
|
212
|
+
return 'z.object({}).passthrough()';
|
|
213
|
+
}
|
|
214
|
+
const entries = sorted.map((field) => {
|
|
215
|
+
const code = field.required ? field.zodCode : `${field.zodCode}.optional()`;
|
|
216
|
+
return `${renderObjectKey(field.name)}: ${code}`;
|
|
217
|
+
});
|
|
218
|
+
return `z.object({\n ${entries.join(',\n ')}\n })`;
|
|
219
|
+
}
|
|
220
|
+
function formatValidationMessage(kind, message) {
|
|
221
|
+
const marker = kind === 'error' ? 'ERROR' : 'WARN';
|
|
222
|
+
return `[${marker}] ${message}`;
|
|
223
|
+
}
|
|
224
|
+
function validateOpenApiDocument(document) {
|
|
225
|
+
const errors = [];
|
|
226
|
+
const warnings = [];
|
|
227
|
+
const operationIds = new Map();
|
|
228
|
+
const toolNames = new Map();
|
|
229
|
+
let enabledTools = 0;
|
|
230
|
+
for (const context of collectOperations(document)) {
|
|
231
|
+
const pointer = `${context.method.toUpperCase()} ${context.path}`;
|
|
232
|
+
const operationId = context.operation.operationId;
|
|
233
|
+
if (operationId) {
|
|
234
|
+
const seenAt = operationIds.get(operationId);
|
|
235
|
+
if (seenAt) {
|
|
236
|
+
errors.push(formatValidationMessage('error', `Duplicate operationId "${operationId}" at ${pointer}. First seen at ${seenAt}.`));
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
operationIds.set(operationId, pointer);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const ai = context.operation['x-ai'];
|
|
243
|
+
if (!ai?.enabled)
|
|
244
|
+
continue;
|
|
245
|
+
enabledTools += 1;
|
|
246
|
+
if (!operationId) {
|
|
247
|
+
errors.push(formatValidationMessage('error', `Missing operationId for enabled tool at ${pointer}.`));
|
|
248
|
+
}
|
|
249
|
+
const toolName = ai.toolName ? normalizeToolName(ai.toolName) : '';
|
|
250
|
+
if (!toolName) {
|
|
251
|
+
errors.push(formatValidationMessage('error', `Missing x-ai.toolName for ${pointer}.`));
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
const seenAt = toolNames.get(toolName);
|
|
255
|
+
if (seenAt) {
|
|
256
|
+
errors.push(formatValidationMessage('error', `Duplicate x-ai.toolName "${toolName}" at ${pointer}. First seen at ${seenAt}.`));
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
toolNames.set(toolName, pointer);
|
|
260
|
+
}
|
|
261
|
+
if (!/^[a-z0-9_]+$/.test(toolName)) {
|
|
262
|
+
warnings.push(formatValidationMessage('warning', `Tool name "${toolName}" at ${pointer} should match ^[a-z0-9_]+$ for model/tooling consistency.`));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (MUTATING_METHODS.has(context.method) && ai.needsApproval === false) {
|
|
266
|
+
errors.push(formatValidationMessage('error', `Mutating endpoint ${pointer} cannot set x-ai.needsApproval to false.`));
|
|
267
|
+
}
|
|
268
|
+
const params = getMergedParameters(document, context);
|
|
269
|
+
const pathParams = new Set(params.filter((param) => param.in === 'path').map((param) => param.name));
|
|
270
|
+
for (const pathParam of listPathParams(context.path)) {
|
|
271
|
+
if (!pathParams.has(pathParam)) {
|
|
272
|
+
errors.push(formatValidationMessage('error', `Path parameter "${pathParam}" in ${pointer} is missing from OpenAPI parameters.`));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (!ai.description && !context.operation.summary && !context.operation.description) {
|
|
276
|
+
warnings.push(formatValidationMessage('warning', `No description found for enabled tool at ${pointer}. Add x-ai.description or summary.`));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
enabledTools,
|
|
281
|
+
errors,
|
|
282
|
+
warnings,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function extractGeneratedToolSpecs(document) {
|
|
286
|
+
const tools = [];
|
|
287
|
+
for (const context of collectOperations(document)) {
|
|
288
|
+
const ai = context.operation['x-ai'];
|
|
289
|
+
if (!ai?.enabled)
|
|
290
|
+
continue;
|
|
291
|
+
if (!context.operation.operationId) {
|
|
292
|
+
throw new Error(`Missing operationId for ${context.method.toUpperCase()} ${context.path}`);
|
|
293
|
+
}
|
|
294
|
+
const toolName = ai.toolName ? normalizeToolName(ai.toolName) : '';
|
|
295
|
+
if (!toolName) {
|
|
296
|
+
throw new Error(`Missing x-ai.toolName for ${context.operation.operationId}`);
|
|
297
|
+
}
|
|
298
|
+
const description = ai.description ??
|
|
299
|
+
context.operation.summary ??
|
|
300
|
+
context.operation.description ??
|
|
301
|
+
`${context.method.toUpperCase()} ${context.path}`;
|
|
302
|
+
tools.push({
|
|
303
|
+
id: context.operation.operationId,
|
|
304
|
+
toolName,
|
|
305
|
+
description,
|
|
306
|
+
method: toMethod(context.method),
|
|
307
|
+
path: normalizePath(context.path),
|
|
308
|
+
inputSchemaCode: createInputSchemaCode(document, context),
|
|
309
|
+
needsApproval: ai.needsApproval ?? MUTATING_METHODS.has(context.method),
|
|
310
|
+
uiActionOnSuccess: ai.uiActionOnSuccess,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
tools.sort((a, b) => a.toolName.localeCompare(b.toolName));
|
|
314
|
+
return tools;
|
|
315
|
+
}
|
|
316
|
+
function renderTypeScriptFromSpecs(specs) {
|
|
317
|
+
const header = `/* eslint-disable */\n/**\n * AUTO-GENERATED FILE.\n * Generated from OpenAPI + x-ai metadata.\n */\n\n`;
|
|
318
|
+
if (specs.length === 0) {
|
|
319
|
+
return `${header}import { z } from 'zod';\nimport { defineEndpointTool } from 'glirastes';\n\nexport const generatedEndpointTools = [] as const;\n`;
|
|
320
|
+
}
|
|
321
|
+
const bodies = specs
|
|
322
|
+
.map((spec) => {
|
|
323
|
+
const uiActionLine = spec.uiActionOnSuccess
|
|
324
|
+
? `\n uiActionOnSuccess: ${renderObject(spec.uiActionOnSuccess, 4)},`
|
|
325
|
+
: '';
|
|
326
|
+
return ` defineEndpointTool({\n id: '${escapeString(spec.id)}',\n toolName: '${escapeString(spec.toolName)}',\n description: '${escapeString(spec.description)}',\n method: '${spec.method}',\n path: '${escapeString(spec.path)}',\n inputSchema: ${spec.inputSchemaCode},\n needsApproval: ${spec.needsApproval},${uiActionLine}\n })`;
|
|
327
|
+
})
|
|
328
|
+
.join(',\n\n');
|
|
329
|
+
return `${header}import { z } from 'zod';\nimport { defineEndpointTool } from 'glirastes';\n\nexport const generatedEndpointTools = [\n${bodies}\n] as const;\n`;
|
|
330
|
+
}
|
|
331
|
+
async function validateOpenApiFile(options) {
|
|
332
|
+
const raw = await (0, promises_1.readFile)(options.inputPath, 'utf8');
|
|
333
|
+
const document = JSON.parse(raw);
|
|
334
|
+
return validateOpenApiDocument(document);
|
|
335
|
+
}
|
|
336
|
+
async function generateFromOpenApiFile(options) {
|
|
337
|
+
const raw = await (0, promises_1.readFile)(options.inputPath, 'utf8');
|
|
338
|
+
const document = JSON.parse(raw);
|
|
339
|
+
const validation = validateOpenApiDocument(document);
|
|
340
|
+
if (validation.errors.length > 0) {
|
|
341
|
+
throw new Error(`OpenAPI validation failed:\n${validation.errors.join('\n')}`);
|
|
342
|
+
}
|
|
343
|
+
const specs = extractGeneratedToolSpecs(document);
|
|
344
|
+
const output = renderTypeScriptFromSpecs(specs);
|
|
345
|
+
await (0, promises_1.writeFile)(options.outputPath, output, 'utf8');
|
|
346
|
+
return validation;
|
|
347
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AudioWorklet processor for real-time audio streaming
|
|
3
|
+
* Converts Float32 audio samples to Int16 format for Deepgram
|
|
4
|
+
*
|
|
5
|
+
* Note: This file is intentionally not unit tested as AudioWorkletProcessor
|
|
6
|
+
* runs in a separate audio rendering thread and is difficult to test in isolation.
|
|
7
|
+
* Integration testing happens in the useDeepgramTranscription hook.
|
|
8
|
+
*/
|
|
9
|
+
declare class AudioWorkletProcessor {
|
|
10
|
+
readonly port: MessagePort;
|
|
11
|
+
process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record<string, Float32Array>): boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function registerProcessor(name: string, processorCtor: typeof AudioWorkletProcessor): void;
|
|
14
|
+
declare class AudioProcessor extends AudioWorkletProcessor {
|
|
15
|
+
process(inputs: Float32Array[][], outputs: Float32Array[][], parameters: Record<string, Float32Array>): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AudioWorklet processor for real-time audio streaming
|
|
4
|
+
* Converts Float32 audio samples to Int16 format for Deepgram
|
|
5
|
+
*
|
|
6
|
+
* Note: This file is intentionally not unit tested as AudioWorkletProcessor
|
|
7
|
+
* runs in a separate audio rendering thread and is difficult to test in isolation.
|
|
8
|
+
* Integration testing happens in the useDeepgramTranscription hook.
|
|
9
|
+
*/
|
|
10
|
+
class AudioProcessor extends AudioWorkletProcessor {
|
|
11
|
+
process(inputs, outputs, parameters) {
|
|
12
|
+
const input = inputs[0]?.[0];
|
|
13
|
+
if (!input || input.length === 0) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
// Convert Float32 (-1.0 to 1.0) to Int16 (-32768 to 32767)
|
|
17
|
+
const int16Data = new Int16Array(input.length);
|
|
18
|
+
for (let i = 0; i < input.length; i++) {
|
|
19
|
+
const sample = Math.max(-1, Math.min(1, input[i] ?? 0));
|
|
20
|
+
int16Data[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
|
|
21
|
+
}
|
|
22
|
+
// Send to main thread
|
|
23
|
+
this.port.postMessage(int16Data, [int16Data.buffer]);
|
|
24
|
+
return true; // Keep processor alive
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
registerProcessor('audio-processor', AudioProcessor);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ChatMessage, SessionConfig, SessionSummary, WireChatMessage } from '../types.js';
|
|
2
|
+
export type HeadersResolver = Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
3
|
+
export interface RestSessionBridgeOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Base URL of the sessions collection. Must NOT end with a trailing
|
|
6
|
+
* slash. Examples: `/api/chat/sessions`, `https://api.example.com/chat/sessions`.
|
|
7
|
+
*/
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
/**
|
|
10
|
+
* Query-string parameters appended to the `list()` GET request. Use
|
|
11
|
+
* this to filter server-side — for example, hide archived sessions
|
|
12
|
+
* from a soft-delete backend:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* listQuery: () => ({ status: 'active' })
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The function is called on every `list()` invocation, so values
|
|
19
|
+
* that depend on runtime state (auth, filters) are re-evaluated.
|
|
20
|
+
*/
|
|
21
|
+
listQuery?: () => Record<string, string>;
|
|
22
|
+
/**
|
|
23
|
+
* Static headers or a function that returns headers per request. Useful
|
|
24
|
+
* for injecting `Authorization`.
|
|
25
|
+
*/
|
|
26
|
+
headers?: HeadersResolver;
|
|
27
|
+
/** `fetch` credentials mode. Default: `'same-origin'`. */
|
|
28
|
+
credentials?: RequestCredentials;
|
|
29
|
+
/**
|
|
30
|
+
* Inject a custom `fetch` — defaults to `globalThis.fetch`. Pass a
|
|
31
|
+
* preconfigured axios-like wrapper via `request` instead if you need
|
|
32
|
+
* interceptors.
|
|
33
|
+
*/
|
|
34
|
+
fetchFn?: typeof fetch;
|
|
35
|
+
/**
|
|
36
|
+
* Full request override. If provided, this function is called for
|
|
37
|
+
* every request and the bridge will not touch `fetchFn`/`headers`.
|
|
38
|
+
* Useful when you already have an axios instance with interceptors.
|
|
39
|
+
*
|
|
40
|
+
* Must return the parsed JSON body (or `undefined` for 204s).
|
|
41
|
+
*/
|
|
42
|
+
request?: (init: {
|
|
43
|
+
method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
44
|
+
url: string;
|
|
45
|
+
body?: unknown;
|
|
46
|
+
}) => Promise<unknown>;
|
|
47
|
+
/**
|
|
48
|
+
* Body used for `create(opts)` POST requests. Default: `{ title }` when
|
|
49
|
+
* a title was supplied, otherwise `{}`. Override when your backend
|
|
50
|
+
* requires extra fields (e.g. `{ execution_types: ['chat'] }`).
|
|
51
|
+
*/
|
|
52
|
+
createBody?: (opts: {
|
|
53
|
+
title?: string;
|
|
54
|
+
}) => unknown;
|
|
55
|
+
/**
|
|
56
|
+
* How to delete a session. Default: `{ method: 'DELETE' }`. Override
|
|
57
|
+
* when your backend uses soft deletes — e.g. archive via
|
|
58
|
+
* `{ method: 'PATCH', body: { status: 'archived' } }`.
|
|
59
|
+
*/
|
|
60
|
+
removeRequest?: (id: string) => {
|
|
61
|
+
method: 'DELETE' | 'PATCH' | 'POST';
|
|
62
|
+
body?: unknown;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Path of the messages sub-collection, relative to a session. Default:
|
|
66
|
+
* `/messages`.
|
|
67
|
+
*/
|
|
68
|
+
messagesPath?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Map a backend session row onto `SessionSummary`. The default handles
|
|
71
|
+
* both `camelCase` and `snake_case` variants of the common fields
|
|
72
|
+
* (`id`, `title` / `name`, `createdAt` / `created_at`, etc.).
|
|
73
|
+
*/
|
|
74
|
+
mapSession?: (row: unknown) => SessionSummary;
|
|
75
|
+
/**
|
|
76
|
+
* Map a backend message row onto the SDK's `ChatMessage` shape. The
|
|
77
|
+
* default reads `{ id, role, content, created_at }` (or `createdAt`),
|
|
78
|
+
* which covers most REST chat backends. Returning a `WireChatMessage`
|
|
79
|
+
* is also fine — the provider coerces it.
|
|
80
|
+
*/
|
|
81
|
+
mapMessage?: (row: unknown) => ChatMessage | WireChatMessage | null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build a `SessionConfig` from a standard REST chat backend.
|
|
85
|
+
*
|
|
86
|
+
* The factory wires the five session hooks (`list`, `load`, `create`,
|
|
87
|
+
* `remove`, `rename`) to a conventional REST layout:
|
|
88
|
+
*
|
|
89
|
+
* | Hook | Request |
|
|
90
|
+
* |----------|--------------------------------------------|
|
|
91
|
+
* | `list` | `GET {baseUrl}` |
|
|
92
|
+
* | `load` | `GET {baseUrl}/{id}{messagesPath}` |
|
|
93
|
+
* | `create` | `POST {baseUrl}` with `createBody(opts)` |
|
|
94
|
+
* | `remove` | `DELETE {baseUrl}/{id}` (or PATCH via `removeRequest`) |
|
|
95
|
+
* | `rename` | `PATCH {baseUrl}/{id}` with `{ title }` |
|
|
96
|
+
*
|
|
97
|
+
* All field-name mapping is done through `mapSession` / `mapMessage`,
|
|
98
|
+
* which have defaults that tolerate both `snake_case` and `camelCase`.
|
|
99
|
+
* For anything exotic (different status codes, non-JSON bodies, etc.),
|
|
100
|
+
* pass `request` and take over the transport entirely.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* // Chaingrow — uses archive-instead-of-delete and a non-standard create body
|
|
105
|
+
* export const chainGrowSessions = createRestSessionBridge({
|
|
106
|
+
* baseUrl: `${API_URL}/chat/sessions`,
|
|
107
|
+
* headers: () => ({ Authorization: `Bearer ${authStore.getState().token}` }),
|
|
108
|
+
* createBody: () => ({ execution_types: ['chat'] }),
|
|
109
|
+
* removeRequest: () => ({ method: 'PATCH', body: { status: 'archived' } }),
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export declare function createRestSessionBridge(options: RestSessionBridgeOptions): SessionConfig;
|