akanjs 3.0.0-alpha.2 → 3.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/base/symbols.ts +4 -0
- package/client/clientRuntime.ts +8 -0
- package/client/cn.ts +7 -0
- package/client/csrTypes.ts +2 -0
- package/client/frameDebug.ts +3 -2
- package/common/Logger.ts +4 -0
- package/common/deepObjectify.ts +21 -7
- package/common/index.ts +14 -0
- package/common/mcpExposure.ts +99 -0
- package/common/pathSet.ts +17 -5
- package/common/routeConvention.ts +30 -0
- package/constant/crystalize.ts +3 -1
- package/constant/fieldInfo.ts +6 -0
- package/constant/getDefault.ts +37 -9
- package/constant/immerify.ts +1 -1
- package/constant/index.ts +2 -0
- package/constant/labelOf.ts +17 -0
- package/constant/mask.ts +60 -0
- package/constant/purify.ts +17 -11
- package/constant/types.ts +14 -12
- package/dictionary/DictionaryLookup.ts +30 -0
- package/dictionary/agent.dictionary.ts +31 -0
- package/dictionary/agentTurn.dictionary.ts +29 -0
- package/dictionary/base.dictionary.ts +8 -0
- package/dictionary/dictInfo.ts +8 -0
- package/dictionary/dictionary.ts +9 -3
- package/dictionary/index.ts +1 -0
- package/document/database.ts +21 -0
- package/document/filterMeta.ts +7 -0
- package/document/index.ts +1 -0
- package/document/into.ts +7 -1
- package/document/noDocumentError.ts +12 -0
- package/fetch/agentTurn.ts +19 -0
- package/fetch/client/fetchClient.ts +71 -13
- package/fetch/client/wsClient.ts +17 -2
- package/fetch/fetchType/endpointFetch.type.ts +10 -4
- package/fetch/index.ts +1 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-wal +0 -0
- package/package.json +11 -9
- package/server/akanApp.ts +30 -34
- package/server/akanOption.ts +65 -7
- package/server/akanServer.ts +172 -7
- package/server/animatedImage.ts +83 -0
- package/server/artifact/routeClientCache.ts +14 -0
- package/server/assetEncoding.ts +47 -0
- package/server/devtools/signalSerializer.ts +2 -2
- package/server/devtools/types.ts +2 -2
- package/server/di/diLifecycle.ts +31 -3
- package/server/di/predefinedAdaptor.ts +6 -0
- package/server/imageOptimizer.ts +33 -46
- package/server/index.ts +1 -2
- package/server/mcp/McpAuth.ts +177 -0
- package/server/mcp/McpDispatcher.ts +245 -0
- package/server/mcp/McpEventStream.ts +76 -0
- package/server/mcp/McpExecutionContext.ts +105 -0
- package/server/mcp/McpRouter.ts +591 -0
- package/server/mcp/index.ts +5 -0
- package/server/resolver/CascadeRunner.ts +1 -1
- package/server/resolver/database.resolver.ts +42 -5
- package/server/resolver/service.resolver.ts +29 -0
- package/server/resolver/signal.resolver.ts +16 -1
- package/server/routeTreeBuilder.ts +2 -44
- package/server/rscWorker.tsx +6 -2
- package/server/subRouteIndexDocument.tsx +61 -0
- package/server/systemPageDocument.tsx +2 -2
- package/server/systemPages.tsx +49 -16
- package/server/vendor/akanjs-fetch.ts +1 -0
- package/server/webRouter.ts +159 -35
- package/service/agent.service.ts +14 -0
- package/service/base.service.ts +2 -1
- package/service/index.ts +1 -0
- package/service/predefinedAdaptor/database.adaptor.ts +78 -24
- package/service/predefinedAdaptor/deepseekLlm.ts +230 -0
- package/service/predefinedAdaptor/index.ts +3 -0
- package/service/predefinedAdaptor/insightQuery.ts +183 -0
- package/service/predefinedAdaptor/llm.adaptor.ts +76 -0
- package/service/predefinedAdaptor/role.adaptor.ts +2 -0
- package/service/predefinedAdaptor/schedule.adaptor.ts +12 -5
- package/service/serviceModule.ts +17 -0
- package/service/types.ts +4 -0
- package/signal/agent/AgentCatalogue.ts +165 -0
- package/signal/agent/index.ts +1 -0
- package/signal/agent.signal.ts +42 -0
- package/signal/agentTurn.ts +8 -0
- package/signal/agentTurnStream.ts +48 -0
- package/signal/base.signal.ts +2 -1
- package/signal/endpointInfo.ts +38 -2
- package/signal/guard.ts +13 -1
- package/signal/guards.ts +52 -1
- package/signal/index.ts +6 -0
- package/signal/mcp/McpDocument.ts +286 -0
- package/signal/mcp/McpProgress.ts +106 -0
- package/signal/mcp/McpUriTemplate.ts +85 -0
- package/signal/mcp/Msg.ts +368 -0
- package/signal/mcp/index.ts +5 -0
- package/signal/mcp/mcpProtocol.ts +120 -0
- package/signal/middleware.ts +7 -3
- package/signal/openapi/openapi.ts +32 -171
- package/signal/schema/JsonSchemaBuilder.ts +211 -0
- package/signal/schema/index.ts +1 -0
- package/signal/signalContext.ts +85 -9
- package/signal/slice.ts +9 -9
- package/signal/types.ts +1 -1
- package/store/action.ts +11 -22
- package/store/actionTag.ts +33 -0
- package/store/agent/AgentBridge.ts +323 -0
- package/store/agent/AgentContext.ts +74 -0
- package/store/agent/AgentPrompts.ts +82 -0
- package/store/agent/AgentVisibility.ts +68 -0
- package/store/agent/ScreenReader.ts +208 -0
- package/store/agent/StoreCatalogue.ts +351 -0
- package/store/agent/StoreSurfaceSource.ts +122 -0
- package/store/agent/index.ts +9 -0
- package/store/agent/storeSurface.ts +28 -0
- package/store/agent/types.ts +50 -0
- package/store/agentic/StToolBuilder.ts +199 -0
- package/store/agentic/attachAgentic.ts +22 -0
- package/store/agentic/index.ts +5 -0
- package/store/agentic/readableValue.ts +17 -0
- package/store/agentic/useStExpose.ts +18 -0
- package/store/agentic/useStState.ts +35 -0
- package/store/baseSt.ts +7 -0
- package/store/databaseStateNames.ts +31 -0
- package/store/formSetterNames.ts +21 -0
- package/store/index.ts +8 -0
- package/store/rootStore.ts +3 -1
- package/store/sliceRole.ts +36 -0
- package/store/state.ts +2 -12
- package/store/store.ts +19 -1
- package/store/storeInstance.ts +165 -20
- package/store/storeRegistry.ts +16 -1
- package/store/types.ts +18 -0
- package/store/withSelector.ts +7 -8
- package/test/registerDom.ts +4 -0
- package/types/base/symbols.d.ts +4 -0
- package/types/client/cn.d.ts +5 -0
- package/types/client/csrTypes.d.ts +2 -0
- package/types/common/Logger.d.ts +2 -0
- package/types/common/deepObjectify.d.ts +4 -2
- package/types/common/index.d.ts +2 -1
- package/types/common/mcpExposure.d.ts +60 -0
- package/types/common/routeConvention.d.ts +8 -0
- package/types/constant/fieldInfo.d.ts +1 -0
- package/types/constant/getDefault.d.ts +5 -0
- package/types/constant/index.d.ts +2 -0
- package/types/constant/labelOf.d.ts +6 -0
- package/types/constant/mask.d.ts +34 -0
- package/types/constant/purify.d.ts +2 -2
- package/types/constant/types.d.ts +2 -2
- package/types/dictionary/DictionaryLookup.d.ts +14 -0
- package/types/dictionary/agent.dictionary.d.ts +1 -0
- package/types/dictionary/agentTurn.dictionary.d.ts +1 -0
- package/types/dictionary/base.dictionary.d.ts +1 -1
- package/types/dictionary/dictInfo.d.ts +6 -0
- package/types/dictionary/dictionary.d.ts +11 -9
- package/types/dictionary/index.d.ts +1 -0
- package/types/document/database.d.ts +20 -0
- package/types/document/filterMeta.d.ts +1 -0
- package/types/document/index.d.ts +1 -0
- package/types/document/into.d.ts +6 -1
- package/types/document/noDocumentError.d.ts +12 -0
- package/types/fetch/agentTurn.d.ts +593 -0
- package/types/fetch/client/fetchClient.d.ts +10 -0
- package/types/fetch/fetchType/endpointFetch.type.d.ts +5 -3
- package/types/fetch/index.d.ts +1 -0
- package/types/server/akanOption.d.ts +35 -7
- package/types/server/akanServer.d.ts +44 -1
- package/types/server/animatedImage.d.ts +7 -0
- package/types/server/artifact/routeClientCache.d.ts +6 -0
- package/types/server/assetEncoding.d.ts +7 -0
- package/types/server/devtools/types.d.ts +2 -2
- package/types/server/di/predefinedAdaptor.d.ts +4 -1
- package/types/server/index.d.ts +0 -2
- package/types/server/mcp/McpAuth.d.ts +62 -0
- package/types/server/mcp/McpDispatcher.d.ts +54 -0
- package/types/server/mcp/McpEventStream.d.ts +18 -0
- package/types/server/mcp/McpExecutionContext.d.ts +44 -0
- package/types/server/mcp/McpRouter.d.ts +60 -0
- package/types/server/mcp/index.d.ts +5 -0
- package/types/server/mcp.d.ts +1 -0
- package/types/server/subRouteIndexDocument.d.ts +8 -0
- package/types/server/systemPageDocument.d.ts +1 -0
- package/types/server/systemPages.d.ts +5 -0
- package/types/server/vendor/akanjs-fetch.d.ts +1 -0
- package/types/service/agent.service.d.ts +12 -0
- package/types/service/base.service.d.ts +4 -0
- package/types/service/index.d.ts +1 -0
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +24 -2
- package/types/service/predefinedAdaptor/deepseekLlm.d.ts +64 -0
- package/types/service/predefinedAdaptor/index.d.ts +3 -0
- package/types/service/predefinedAdaptor/insightQuery.d.ts +50 -0
- package/types/service/predefinedAdaptor/llm.adaptor.d.ts +68 -0
- package/types/service/predefinedAdaptor/role.adaptor.d.ts +2 -0
- package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +10 -6
- package/types/service/types.d.ts +4 -1
- package/types/signal/agent/AgentCatalogue.d.ts +100 -0
- package/types/signal/agent/index.d.ts +1 -0
- package/types/signal/agent.d.ts +1 -0
- package/types/signal/agent.signal.d.ts +29 -0
- package/types/signal/agentTurn.d.ts +9 -0
- package/types/signal/agentTurnStream.d.ts +16 -0
- package/types/signal/base.signal.d.ts +1 -1
- package/types/signal/endpointInfo.d.ts +21 -3
- package/types/signal/guard.d.ts +11 -0
- package/types/signal/guards.d.ts +22 -1
- package/types/signal/index.d.ts +6 -0
- package/types/signal/mcp/McpDocument.d.ts +65 -0
- package/types/signal/mcp/McpProgress.d.ts +40 -0
- package/types/signal/mcp/McpUriTemplate.d.ts +26 -0
- package/types/signal/mcp/Msg.d.ts +143 -0
- package/types/signal/mcp/index.d.ts +5 -0
- package/types/signal/mcp/mcpProtocol.d.ts +107 -0
- package/types/signal/mcp.d.ts +1 -0
- package/types/signal/openapi/openapi.d.ts +3 -3
- package/types/signal/schema/JsonSchemaBuilder.d.ts +47 -0
- package/types/signal/schema/index.d.ts +1 -0
- package/types/signal/schema.d.ts +1 -0
- package/types/signal/signalContext.d.ts +16 -1
- package/types/signal/slice.d.ts +8 -8
- package/types/signal/types.d.ts +1 -1
- package/types/store/actionTag.d.ts +21 -0
- package/types/store/agent/AgentBridge.d.ts +77 -0
- package/types/store/agent/AgentContext.d.ts +16 -0
- package/types/store/agent/AgentPrompts.d.ts +31 -0
- package/types/store/agent/AgentVisibility.d.ts +21 -0
- package/types/store/agent/ScreenReader.d.ts +11 -0
- package/types/store/agent/StoreCatalogue.d.ts +26 -0
- package/types/store/agent/StoreSurfaceSource.d.ts +18 -0
- package/types/store/agent/index.d.ts +9 -0
- package/types/store/agent/storeSurface.d.ts +14 -0
- package/types/store/agent/types.d.ts +49 -0
- package/types/store/agent.d.ts +1 -0
- package/types/store/agentic/StToolBuilder.d.ts +41 -0
- package/types/store/agentic/attachAgentic.d.ts +14 -0
- package/types/store/agentic/index.d.ts +5 -0
- package/types/store/agentic/readableValue.d.ts +3 -0
- package/types/store/agentic/useStExpose.d.ts +8 -0
- package/types/store/agentic/useStState.d.ts +12 -0
- package/types/store/agentic.d.ts +1 -0
- package/types/store/baseSt.d.ts +29 -22
- package/types/store/databaseStateNames.d.ts +25 -0
- package/types/store/formSetterNames.d.ts +16 -0
- package/types/store/index.d.ts +7 -0
- package/types/store/rootStore.d.ts +5 -1
- package/types/store/sliceRole.d.ts +25 -0
- package/types/store/store.d.ts +7 -2
- package/types/store/storeInstance.d.ts +33 -1
- package/types/store/storeRegistry.d.ts +5 -0
- package/types/store/types.d.ts +15 -0
- package/types/store/withSelector.d.ts +7 -8
- package/types/test/registerDom.d.ts +1 -0
- package/types/ui/Agent/Approval.d.ts +7 -0
- package/types/ui/Agent/Bubble.d.ts +13 -0
- package/types/ui/Agent/Chat.d.ts +24 -0
- package/types/ui/Agent/Context.d.ts +9 -0
- package/types/ui/Agent/Dock.d.ts +16 -0
- package/types/ui/Agent/Guide.d.ts +9 -0
- package/types/ui/Agent/Section.d.ts +10 -0
- package/types/ui/Agent/StateKey.d.ts +16 -0
- package/types/ui/Agent/Tool.d.ts +15 -0
- package/types/ui/Agent/Transcript.d.ts +13 -0
- package/types/ui/Agent/Zone.d.ts +23 -0
- package/types/ui/Agent/fetchRunner.d.ts +12 -0
- package/types/ui/Agent/index.d.ts +17 -0
- package/types/ui/Agent/index_.d.ts +1 -0
- package/types/ui/Agent/sessionHistory.d.ts +12 -0
- package/types/ui/Agent.d.ts +1 -0
- package/types/ui/Badge.d.ts +1 -1
- package/types/ui/Button.d.ts +1 -1
- package/types/ui/CsrImage.d.ts +1 -1
- package/types/ui/Dropdown.d.ts +2 -0
- package/types/ui/Image.d.ts +3 -3
- package/types/ui/Layout/BottomInset.d.ts +2 -1
- package/types/ui/Layout/index.d.ts +1 -1
- package/types/ui/Signal/style.d.ts +4 -1
- package/types/ui/UiOverride/context.d.ts +14 -2
- package/types/ui/agentAttrs.d.ts +14 -0
- package/types/ui/index.d.ts +4 -1
- package/types/ui/overlayLayer.d.ts +24 -0
- package/types/ui/recipe/badgeRecipe.d.ts +7 -3
- package/types/ui/recipe/buttonRecipe.d.ts +7 -3
- package/types/ui/recipe/inputRecipe.d.ts +5 -1
- package/types/vendor/use-agentic/AgentProvider.d.ts +18 -0
- package/types/vendor/use-agentic/AgentScope.d.ts +9 -0
- package/types/vendor/use-agentic/AgentSession.d.ts +50 -0
- package/types/vendor/use-agentic/Agentic.d.ts +21 -0
- package/types/vendor/use-agentic/AgenticSurface.d.ts +44 -0
- package/types/vendor/use-agentic/httpRunner.d.ts +15 -0
- package/types/vendor/use-agentic/index.d.ts +13 -0
- package/types/vendor/use-agentic/surfaceContext.d.ts +5 -0
- package/types/vendor/use-agentic/types.d.ts +133 -0
- package/types/vendor/use-agentic/useAgent.d.ts +4 -0
- package/types/vendor/use-agentic/useAgentGuide.d.ts +6 -0
- package/types/vendor/use-agentic/useAgentResource.d.ts +7 -0
- package/types/vendor/use-agentic/useAgentState.d.ts +13 -0
- package/types/vendor/use-agentic/useAgentTool.d.ts +16 -0
- package/types/vendor/use-agentic.d.ts +1 -0
- package/types/webkit/index.d.ts +3 -0
- package/types/webkit/lazy.d.ts +12 -0
- package/types/webkit/useCsrValues.d.ts +3 -3
- package/types/webkit/useEscapeKey.d.ts +5 -0
- package/types/webkit/useFrameRuntime.d.ts +6 -1
- package/types/webkit/useScreenScope.d.ts +18 -0
- package/ui/Agent/Approval.tsx +29 -0
- package/ui/Agent/Bubble.tsx +74 -0
- package/ui/Agent/Chat.tsx +225 -0
- package/ui/Agent/Context.tsx +38 -0
- package/ui/Agent/Dock.tsx +72 -0
- package/ui/Agent/Guide.tsx +16 -0
- package/ui/Agent/Section.tsx +24 -0
- package/ui/Agent/StateKey.tsx +44 -0
- package/ui/Agent/Tool.tsx +66 -0
- package/ui/Agent/Transcript.tsx +33 -0
- package/ui/Agent/Zone.tsx +48 -0
- package/ui/Agent/fetchRunner.ts +30 -0
- package/ui/Agent/index.ts +12 -0
- package/ui/Agent/index_.tsx +4 -0
- package/ui/Agent/sessionHistory.ts +33 -0
- package/ui/Badge.tsx +3 -3
- package/ui/BottomSheet.tsx +5 -0
- package/ui/Button.tsx +6 -2
- package/ui/Constant/Doc.tsx +1 -1
- package/ui/CsrImage.tsx +1 -1
- package/ui/Data/ListContainer.tsx +1 -1
- package/ui/DatePicker.tsx +5 -4
- package/ui/Dialog/Modal.tsx +12 -15
- package/ui/DraggableList.tsx +3 -1
- package/ui/Dropdown.tsx +33 -11
- package/ui/Field.tsx +30 -16
- package/ui/Image.tsx +3 -3
- package/ui/Input.tsx +14 -5
- package/ui/Layout/BottomInset.tsx +6 -1
- package/ui/Load/Units.tsx +11 -2
- package/ui/Load/View.tsx +7 -2
- package/ui/Loading/ProgressBar.tsx +8 -1
- package/ui/Menu.tsx +7 -8
- package/ui/Model/EditModal.tsx +37 -2
- package/ui/Model/SureToRemove.tsx +2 -1
- package/ui/Model/index_.tsx +42 -15
- package/ui/ObjectId.tsx +3 -4
- package/ui/Pagination.tsx +3 -4
- package/ui/Popconfirm.tsx +8 -7
- package/ui/Select.tsx +6 -4
- package/ui/Signal/RestApi.tsx +43 -16
- package/ui/Signal/WebSocket.tsx +1 -1
- package/ui/Signal/style.ts +6 -1
- package/ui/Switch.tsx +2 -0
- package/ui/System/CSR.tsx +6 -2
- package/ui/System/ThemeToggle.tsx +55 -33
- package/ui/ToggleSelect.tsx +4 -3
- package/ui/Tooltip.tsx +2 -1
- package/ui/UiOverride/context.ts +14 -2
- package/ui/agentAttrs.ts +19 -0
- package/ui/index.ts +10 -1
- package/ui/overlayLayer.ts +39 -0
- package/ui/recipe/badgeRecipe.ts +22 -3
- package/ui/recipe/buttonRecipe.ts +51 -2
- package/ui/recipe/factory.ts +2 -2
- package/ui/recipe/inputRecipe.ts +18 -4
- package/vendor/use-agentic/AgentProvider.tsx +39 -0
- package/vendor/use-agentic/AgentScope.tsx +20 -0
- package/vendor/use-agentic/AgentSession.ts +292 -0
- package/vendor/use-agentic/Agentic.tsx +44 -0
- package/vendor/use-agentic/AgenticSurface.ts +294 -0
- package/vendor/use-agentic/WIRE.md +57 -0
- package/vendor/use-agentic/httpRunner.ts +115 -0
- package/vendor/use-agentic/index.ts +14 -0
- package/vendor/use-agentic/surfaceContext.ts +9 -0
- package/vendor/use-agentic/types.ts +144 -0
- package/vendor/use-agentic/useAgent.ts +17 -0
- package/vendor/use-agentic/useAgentGuide.ts +16 -0
- package/vendor/use-agentic/useAgentResource.ts +30 -0
- package/vendor/use-agentic/useAgentState.ts +61 -0
- package/vendor/use-agentic/useAgentTool.ts +55 -0
- package/webkit/bootCsr.tsx +2 -33
- package/webkit/index.ts +3 -0
- package/webkit/lazy.tsx +27 -3
- package/webkit/useCsrValues.ts +121 -4
- package/webkit/useEscapeKey.tsx +42 -0
- package/webkit/useFrameRuntime.ts +65 -32
- package/webkit/useScreenScope.tsx +49 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { leakingFieldsOf, type MaskModel, mask } from "akanjs/constant";
|
|
2
|
+
import type { JsonSchema } from "../schema";
|
|
3
|
+
|
|
4
|
+
export type PromptRole = "user" | "assistant";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* What a client may do with a block when it cannot keep all of them.
|
|
8
|
+
*
|
|
9
|
+
* `priority` is the field that matters here: a prompt this server assembles is often mostly context — a document
|
|
10
|
+
* embedded beside the one line asking for something — and a client with a full window drops blocks by this number
|
|
11
|
+
* rather than by position. Leaving it off means every block is equally droppable, so the instruction can go and
|
|
12
|
+
* the attachment stay.
|
|
13
|
+
*/
|
|
14
|
+
export interface PromptAnnotations {
|
|
15
|
+
/** Who the block is for. A note meant only for the model is `["assistant"]`, so a UI need not render it. */
|
|
16
|
+
audience?: PromptRole[];
|
|
17
|
+
/** 0 is "drop this first", 1 is "this is the point of the prompt". Anything outside the range is refused. */
|
|
18
|
+
priority?: number;
|
|
19
|
+
/** ISO 8601. Lets a client tell a re-fetched resource from the copy it already holds. */
|
|
20
|
+
lastModified?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PromptTextContent {
|
|
24
|
+
type: "text";
|
|
25
|
+
text: string;
|
|
26
|
+
annotations?: PromptAnnotations;
|
|
27
|
+
}
|
|
28
|
+
export interface PromptBinaryContent {
|
|
29
|
+
type: "image" | "audio";
|
|
30
|
+
data: string;
|
|
31
|
+
mimeType: string;
|
|
32
|
+
annotations?: PromptAnnotations;
|
|
33
|
+
}
|
|
34
|
+
export interface PromptResourceLinkContent {
|
|
35
|
+
type: "resource_link";
|
|
36
|
+
uri: string;
|
|
37
|
+
/** Required by the spec: `ResourceLink` extends `BaseMetadata`, whose `name` is not optional. */
|
|
38
|
+
name: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
mimeType?: string;
|
|
41
|
+
annotations?: PromptAnnotations;
|
|
42
|
+
}
|
|
43
|
+
export interface PromptEmbeddedResourceContent {
|
|
44
|
+
type: "resource";
|
|
45
|
+
resource: { uri: string; mimeType: string; text: string };
|
|
46
|
+
annotations?: PromptAnnotations;
|
|
47
|
+
}
|
|
48
|
+
export type PromptContent =
|
|
49
|
+
| PromptTextContent
|
|
50
|
+
| PromptBinaryContent
|
|
51
|
+
| PromptResourceLinkContent
|
|
52
|
+
| PromptEmbeddedResourceContent;
|
|
53
|
+
|
|
54
|
+
export interface PromptMessage {
|
|
55
|
+
role: PromptRole;
|
|
56
|
+
content: PromptContent;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** What a `prompt()` exec may return. A bare string is the 80% case and is wrapped into one user message. */
|
|
60
|
+
export type PromptResult = string | PromptMessage[];
|
|
61
|
+
|
|
62
|
+
/** Enough of the `File` model to link or inline it, structural so the framework does not depend on the lib. */
|
|
63
|
+
export interface PromptFileSource {
|
|
64
|
+
url: string;
|
|
65
|
+
filename?: string;
|
|
66
|
+
mimetype?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A model class, named by the caller so an attachment can be masked by what it *is* rather than by what it still
|
|
71
|
+
* carries at runtime. The same model any other audience masks by — see `mask` in `akanjs/constant`.
|
|
72
|
+
*/
|
|
73
|
+
export type PromptModel = MaskModel;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The string fields each block type must carry, and the set of legal types at once.
|
|
77
|
+
*
|
|
78
|
+
* A client parses `prompts/get` against a discriminated union, so a block missing one of these is not a thinner
|
|
79
|
+
* block — it matches no member and the whole reply throws on the client. `resource` carries a nested shape instead
|
|
80
|
+
* and is checked on its own.
|
|
81
|
+
*/
|
|
82
|
+
const contentFields = new Map<string, readonly string[]>([
|
|
83
|
+
["text", ["text"]],
|
|
84
|
+
["image", ["data", "mimeType"]],
|
|
85
|
+
["audio", ["data", "mimeType"]],
|
|
86
|
+
["resource_link", ["uri", "name"]],
|
|
87
|
+
["resource", []],
|
|
88
|
+
]);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Builds the messages a `prompt()` endpoint returns.
|
|
92
|
+
*
|
|
93
|
+
* Named `Msg` rather than `msg` because `akanjs/dictionary` already exports a `msg` for toasts.
|
|
94
|
+
*
|
|
95
|
+
* Every attachment builder carries the `user` role. Content the server assembles is context handed *to* the
|
|
96
|
+
* model, which is what the user role means; an assistant-role attachment would be the server putting words in the
|
|
97
|
+
* model's mouth. That is only meaningful for few-shot text, which `Msg.assistant` covers.
|
|
98
|
+
*/
|
|
99
|
+
export class Msg {
|
|
100
|
+
/**
|
|
101
|
+
* What every `prompt()` route answers with, as JSON Schema, for the app's OpenAPI document.
|
|
102
|
+
*
|
|
103
|
+
* A prompt declares `Any` on the wire, so the generated response schema was `{}` — a documented `GET` whose body
|
|
104
|
+
* the document could not describe, which is half of the agreement the HTTP route was mounted for. The shape is
|
|
105
|
+
* fixed by the protocol rather than by the endpoint, so it is written once, here: the block types and the fields
|
|
106
|
+
* each must carry come off `contentFields`, so a type added to one cannot describe itself out of the other.
|
|
107
|
+
*/
|
|
108
|
+
static readonly schema: JsonSchema = {
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {
|
|
111
|
+
role: { type: "string", enum: ["user", "assistant"] },
|
|
112
|
+
content: {
|
|
113
|
+
oneOf: [...contentFields].map(([type, fields]) => ({
|
|
114
|
+
type: "object",
|
|
115
|
+
properties: {
|
|
116
|
+
type: { const: type },
|
|
117
|
+
...Object.fromEntries(fields.map((field) => [field, { type: "string" }])),
|
|
118
|
+
|
|
119
|
+
...(type === "resource"
|
|
120
|
+
? {
|
|
121
|
+
resource: {
|
|
122
|
+
type: "object",
|
|
123
|
+
properties: { uri: { type: "string" }, mimeType: { type: "string" }, text: { type: "string" } },
|
|
124
|
+
required: ["uri"],
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
: {}),
|
|
128
|
+
...(type === "resource_link" ? { description: { type: "string" }, mimeType: { type: "string" } } : {}),
|
|
129
|
+
annotations: {
|
|
130
|
+
type: "object",
|
|
131
|
+
properties: {
|
|
132
|
+
audience: { type: "array", items: { type: "string", enum: ["user", "assistant"] } },
|
|
133
|
+
priority: { type: "number", minimum: 0, maximum: 1 },
|
|
134
|
+
lastModified: { type: "string", format: "date-time" },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
required: ["type", ...fields, ...(type === "resource" ? ["resource"] : [])],
|
|
139
|
+
additionalProperties: false,
|
|
140
|
+
})),
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
required: ["role", "content"],
|
|
144
|
+
additionalProperties: false,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
static user(text: string, annotations?: PromptAnnotations): PromptMessage {
|
|
148
|
+
return { role: "user", content: Msg.#annotated({ type: "text", text }, annotations) };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static assistant(text: string, annotations?: PromptAnnotations): PromptMessage {
|
|
152
|
+
return { role: "assistant", content: Msg.#annotated({ type: "text", text }, annotations) };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Embeds the value itself. The payload travels in the prompt, so prefer `link` for anything large.
|
|
157
|
+
*
|
|
158
|
+
* Name the model it is an instance of and the `hidden`/`secret` fields are stripped before it goes out:
|
|
159
|
+
* `Msg.resource(uri, order, { model: cnst.Order })`. A payload you assembled yourself needs no model and is
|
|
160
|
+
* embedded as given — but one that still carries a document's secret fields is refused rather than sent, so
|
|
161
|
+
* the rule is the same either way: a document travels masked, or it does not travel.
|
|
162
|
+
*/
|
|
163
|
+
static resource(
|
|
164
|
+
uri: string,
|
|
165
|
+
value: unknown,
|
|
166
|
+
{ model, ...annotations }: { model?: PromptModel } & PromptAnnotations = {},
|
|
167
|
+
): PromptMessage {
|
|
168
|
+
const payload = model ? Msg.mask(model, value) : Msg.#assertMasked(uri, value);
|
|
169
|
+
return {
|
|
170
|
+
role: "user",
|
|
171
|
+
content: Msg.#annotated(
|
|
172
|
+
{ type: "resource", resource: { uri, mimeType: "application/json", text: JSON.stringify(payload) } },
|
|
173
|
+
annotations,
|
|
174
|
+
),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Strips what a model marks `hidden` or `secret`, by the model the caller names rather than by the one the
|
|
180
|
+
* value happens to still carry.
|
|
181
|
+
*
|
|
182
|
+
* That distinction is the whole fix. A check that reads the class off the value can only mask what arrives as an
|
|
183
|
+
* instance, so a `{ ...doc }` spread, a `toJSON()`, or a round-trip through `JSON.stringify` reached the wire
|
|
184
|
+
* with the metadata already gone and nothing could be done about it. A named model is metadata the value cannot
|
|
185
|
+
* lose, so a hydrated document and a plain object copied out of one mask identically.
|
|
186
|
+
*
|
|
187
|
+
* This is the field half of `resolveReturn` and deliberately not the whole of it. That one also loads every
|
|
188
|
+
* relation it walks past, which is right for a query's return value and wrong for an attachment, where it would
|
|
189
|
+
* turn embedding one document into a fan of queries nobody asked for. So a populated relation is masked in
|
|
190
|
+
* place and one that is still an id is left as an id.
|
|
191
|
+
*
|
|
192
|
+
* Public because a payload can be an assembly of several documents — `{ order, customer }` names no single
|
|
193
|
+
* model, so each piece is masked on its way in.
|
|
194
|
+
*
|
|
195
|
+
* Returns `unknown` rather than the argument's type, because what comes back is missing fields that type still
|
|
196
|
+
* promises. The value's only destination is a JSON payload, so nothing downstream wanted the type anyway.
|
|
197
|
+
*/
|
|
198
|
+
static mask(model: PromptModel, value: unknown): unknown {
|
|
199
|
+
return mask(model, value);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Points at something without paying for it. The client decides whether to fetch, and skips what it already
|
|
204
|
+
* holds — so a prompt that references twenty documents costs twenty URIs rather than twenty payloads.
|
|
205
|
+
*/
|
|
206
|
+
static link(
|
|
207
|
+
source: string | PromptFileSource,
|
|
208
|
+
{ name, description, ...annotations }: { name?: string; description?: string } & PromptAnnotations = {},
|
|
209
|
+
): PromptMessage {
|
|
210
|
+
const file = typeof source === "string" ? null : source;
|
|
211
|
+
const uri = typeof source === "string" ? source : source.url;
|
|
212
|
+
return {
|
|
213
|
+
role: "user",
|
|
214
|
+
content: Msg.#annotated(
|
|
215
|
+
{
|
|
216
|
+
type: "resource_link",
|
|
217
|
+
uri,
|
|
218
|
+
name: Msg.#linkName(uri, name ?? file?.filename),
|
|
219
|
+
...(description ? { description } : {}),
|
|
220
|
+
...(file?.mimetype ? { mimeType: file.mimetype } : {}),
|
|
221
|
+
},
|
|
222
|
+
annotations,
|
|
223
|
+
),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Never absent, because the spec's `name` is required and a client SDK parses the block against a union it then
|
|
229
|
+
* matches nothing in — a link with no name is not a nameless link, it is a `prompts/get` that throws.
|
|
230
|
+
*
|
|
231
|
+
* The last path segment is the fallback rather than the whole URI: for `akan://order/42` it is the identifier a
|
|
232
|
+
* person reading the list would use, and for a file URL it is the filename we would have used anyway.
|
|
233
|
+
*/
|
|
234
|
+
static #linkName(uri: string, name?: string) {
|
|
235
|
+
if (name) return name;
|
|
236
|
+
const segment = uri.split(/[?#]/)[0]?.split("/").filter(Boolean).pop();
|
|
237
|
+
return segment ?? uri;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static image(data: string, mimeType: string, annotations?: PromptAnnotations): PromptMessage {
|
|
241
|
+
return { role: "user", content: Msg.#annotated({ type: "image", data, mimeType }, annotations) };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static audio(data: string, mimeType: string, annotations?: PromptAnnotations): PromptMessage {
|
|
245
|
+
return { role: "user", content: Msg.#annotated({ type: "audio", data, mimeType }, annotations) };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Inlines a file as base64, costing roughly 1.33× its bytes in the prompt. Worth it only when the client
|
|
250
|
+
* cannot fetch the URL itself — a public asset is cheaper as `Msg.link`. Fetched as this process, so a file
|
|
251
|
+
* behind a caller-scoped signed URL needs its bytes passed to `Msg.image` instead.
|
|
252
|
+
*/
|
|
253
|
+
static async imageOf(file: PromptFileSource, annotations?: PromptAnnotations): Promise<PromptMessage> {
|
|
254
|
+
const response = await fetch(file.url, { signal: AbortSignal.timeout(20_000) });
|
|
255
|
+
if (!response.ok) throw new Error(`Failed to inline ${file.url}: ${response.status}`);
|
|
256
|
+
const mimeType = file.mimetype ?? response.headers.get("content-type") ?? "application/octet-stream";
|
|
257
|
+
return Msg.image(Buffer.from(await response.arrayBuffer()).toString("base64"), mimeType, annotations);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Refuses an undeclared payload that still carries a document's secret fields, rather than sending it.
|
|
262
|
+
*
|
|
263
|
+
* A warning was the older answer, on the reasoning that masking off the value's own class would reach only the
|
|
264
|
+
* payloads that still had one — half masked, half not, and an author who believes prompts are masked is worse
|
|
265
|
+
* off on the unmasked half. `mask` removes that objection by taking the model as an argument instead, so there
|
|
266
|
+
* is now a way to be right about every payload and this is the shape that did not take it.
|
|
267
|
+
*
|
|
268
|
+
* It throws only where it can prove a leak: a value whose class says those fields exist and whose own keys say
|
|
269
|
+
* they are populated. A `Light<Model>`, or anything assembled by hand, declares no such fields and passes.
|
|
270
|
+
*/
|
|
271
|
+
static #assertMasked(uri: string, value: unknown) {
|
|
272
|
+
for (const sample of Msg.#samples(value)) Msg.#assertSample(uri, sample);
|
|
273
|
+
return value;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* The values a refusal could be about: the payload, and — when the payload is a plain object — one level into it.
|
|
278
|
+
*
|
|
279
|
+
* A list is homogeneous in practice, so its first element answers for it; walking every element to decide
|
|
280
|
+
* whether to refuse would cost more than the thing it is checking.
|
|
281
|
+
*
|
|
282
|
+
* The level down is what makes the common assembly reachable. A document rarely travels alone — it arrives as
|
|
283
|
+
* `{ order }` or `{ order, customer }` — and a plain object's own constructor carries no field metadata, so a
|
|
284
|
+
* check that stopped at the outer value saw neither the wrapper (which has nothing to show) nor what it wrapped.
|
|
285
|
+
* It stops there rather than recursing: a payload nested two deep is one somebody assembled deliberately, and no
|
|
286
|
+
* depth reaches metadata a spread has already thrown away.
|
|
287
|
+
*/
|
|
288
|
+
static #samples(value: unknown): Record<string, unknown>[] {
|
|
289
|
+
const sample = (Array.isArray(value) ? value[0] : value) as Record<string, unknown> | null | undefined;
|
|
290
|
+
if (!sample || typeof sample !== "object") return [];
|
|
291
|
+
if (sample.constructor !== Object) return [sample];
|
|
292
|
+
return Object.values(sample).flatMap((nested) => {
|
|
293
|
+
const inner = (Array.isArray(nested) ? nested[0] : nested) as Record<string, unknown> | null | undefined;
|
|
294
|
+
return inner && typeof inner === "object" && inner.constructor !== Object ? [inner] : [];
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
static #assertSample(uri: string, sample: Record<string, unknown>) {
|
|
299
|
+
const model = sample.constructor as PromptModel | undefined;
|
|
300
|
+
const leaking = model ? leakingFieldsOf(model, sample) : [];
|
|
301
|
+
if (!leaking.length) return;
|
|
302
|
+
throw new Error(
|
|
303
|
+
`Msg.resource("${uri}") embeds ${model?.name} with its hidden/secret fields populated: ${leaking.join(", ")}. Name the model so they are stripped — Msg.resource(uri, value, { model: cnst.${model?.name} }), or Msg.mask(cnst.${model?.name}, value) for one piece of an assembled payload.`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* An empty annotation object is dropped rather than emitted: a block carrying `annotations: {}` reads to a
|
|
309
|
+
* client as a deliberate "no audience, no priority", which is not the same as saying nothing.
|
|
310
|
+
*
|
|
311
|
+
* A `priority` outside 0..1 throws instead of being clamped. The spec's range is what gives the number its
|
|
312
|
+
* meaning, and a client that meets 5 is free to ignore the field entirely — so a silent clamp would turn a
|
|
313
|
+
* typo into blocks dropped in an order nobody chose.
|
|
314
|
+
*/
|
|
315
|
+
static #annotated<T extends PromptContent>(content: T, annotations?: PromptAnnotations): T {
|
|
316
|
+
if (!annotations || !Object.keys(annotations).length) return content;
|
|
317
|
+
const { priority } = annotations;
|
|
318
|
+
if (priority !== undefined && (priority < 0 || priority > 1))
|
|
319
|
+
throw new Error(`Prompt annotation priority must be between 0 and 1, got ${priority}`);
|
|
320
|
+
return { ...content, annotations };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The one runtime check on a prompt's return value. `prompt()` carries `Any` on the wire so the signal
|
|
325
|
+
* pipeline hands the value back untouched — nothing upstream would notice a malformed message, and the client
|
|
326
|
+
* would receive it as a valid prompt.
|
|
327
|
+
*/
|
|
328
|
+
static normalize(value: unknown): PromptMessage[] {
|
|
329
|
+
if (typeof value === "string") return [Msg.user(value)];
|
|
330
|
+
if (!Array.isArray(value)) throw new Error(`A prompt must return a string or PromptMessage[], got ${typeof value}`);
|
|
331
|
+
value.forEach((message, idx) => {
|
|
332
|
+
Msg.#assertMessage(message, idx);
|
|
333
|
+
});
|
|
334
|
+
return value as PromptMessage[];
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Checked down to the fields, not just the discriminator: the shapes this framework can build wrongly are all
|
|
339
|
+
* inside a block a client would then reject, and a check that stops at `content.type` cannot see any of them.
|
|
340
|
+
*/
|
|
341
|
+
static #assertMessage(message: unknown, idx: number) {
|
|
342
|
+
const { role, content } = (message ?? {}) as { role?: unknown; content?: unknown };
|
|
343
|
+
if (role !== "user" && role !== "assistant") throw new Error(`Prompt message ${idx} has role "${String(role)}"`);
|
|
344
|
+
const block = (content ?? {}) as Record<string, unknown>;
|
|
345
|
+
const fields = typeof block.type === "string" ? contentFields.get(block.type) : undefined;
|
|
346
|
+
if (!fields) throw new Error(`Prompt message ${idx} has content type "${String(block.type)}"`);
|
|
347
|
+
const missing = fields.filter((field) => typeof block[field] !== "string" || !block[field]);
|
|
348
|
+
if (missing.length) throw new Error(`Prompt message ${idx} (${block.type}) is missing ${missing.join(", ")}`);
|
|
349
|
+
if (block.type === "resource") Msg.#assertResource(block.resource, idx);
|
|
350
|
+
Msg.#assertPriority(block.annotations, idx);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** The one nested block, and the one whose payload may arrive as either `text` or a base64 `blob`. */
|
|
354
|
+
static #assertResource(resource: unknown, idx: number) {
|
|
355
|
+
const { uri, text, blob } = (resource ?? {}) as Record<string, unknown>;
|
|
356
|
+
if (typeof uri !== "string" || !uri) throw new Error(`Prompt message ${idx} (resource) is missing resource.uri`);
|
|
357
|
+
if (typeof text !== "string" && typeof blob !== "string")
|
|
358
|
+
throw new Error(`Prompt message ${idx} (resource) has neither resource.text nor resource.blob`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** Same range the builders enforce, for a message an author assembled without them. */
|
|
362
|
+
static #assertPriority(annotations: unknown, idx: number) {
|
|
363
|
+
const priority = (annotations as { priority?: unknown } | null)?.priority;
|
|
364
|
+
if (priority === undefined) return;
|
|
365
|
+
if (typeof priority !== "number" || priority < 0 || priority > 1)
|
|
366
|
+
throw new Error(`Prompt message ${idx} has annotations.priority "${String(priority)}", not between 0 and 1`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire vocabulary for the MCP revisions this server answers.
|
|
3
|
+
*
|
|
4
|
+
* `2026-07-28` made the protocol stateless — no `initialize`, no session id, no server-opened stream — which is
|
|
5
|
+
* what makes a single `POST /mcp` route sufficient. Everything before it is the *legacy* era, still what shipping
|
|
6
|
+
* clients speak (measured: Claude Code 2.1.226 negotiates `2025-11-25`), and supporting it costs almost nothing
|
|
7
|
+
* here because a legacy server *may* decline to issue `Mcp-Session-Id`: without one the client sends no session
|
|
8
|
+
* header and never asks to resume a stream, so both eras run over the same stateless handler.
|
|
9
|
+
*
|
|
10
|
+
* `2025-06-18` is listed for the same reason. The surface this server actually implements — POST-only Streamable
|
|
11
|
+
* HTTP, no sessions, no server-initiated requests — is wire-identical between the two legacy revisions, and a
|
|
12
|
+
* client that proposes a version the server does not list is told to disconnect. Naming only the one revision that
|
|
13
|
+
* was measured turned "we tested against this" into "we refuse everything else".
|
|
14
|
+
*/
|
|
15
|
+
export const MCP_MODERN_VERSION = "2026-07-28";
|
|
16
|
+
export const MCP_LEGACY_VERSION = "2025-11-25";
|
|
17
|
+
export const MCP_LEGACY_PRIOR_VERSION = "2025-06-18";
|
|
18
|
+
/** Newest first — `server/discover` and `initialize` both answer with this order, and `#negotiate` reads the ends. */
|
|
19
|
+
export const MCP_SUPPORTED_VERSIONS = [MCP_MODERN_VERSION, MCP_LEGACY_VERSION, MCP_LEGACY_PRIOR_VERSION] as const;
|
|
20
|
+
export type McpProtocolVersion = (typeof MCP_SUPPORTED_VERSIONS)[number];
|
|
21
|
+
|
|
22
|
+
export type McpEra = "modern" | "legacy";
|
|
23
|
+
|
|
24
|
+
export const MCP_META_PREFIX = "io.modelcontextprotocol/";
|
|
25
|
+
export const MCP_META_PROTOCOL_VERSION = `${MCP_META_PREFIX}protocolVersion`;
|
|
26
|
+
export const MCP_META_CLIENT_CAPABILITIES = `${MCP_META_PREFIX}clientCapabilities`;
|
|
27
|
+
export const MCP_META_CLIENT_INFO = `${MCP_META_PREFIX}clientInfo`;
|
|
28
|
+
export const MCP_META_SERVER_INFO = `${MCP_META_PREFIX}serverInfo`;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `-32020`..`-32099` is reserved by the spec, so nothing outside this table may be minted in that band.
|
|
32
|
+
* `-32002` (resource not found) is retired in the modern revision; unknown resources are `invalidParams`.
|
|
33
|
+
*
|
|
34
|
+
* The band also defines `-32021 missingRequiredClientCapability`, which is absent because this server requires
|
|
35
|
+
* none: it never samples, elicits, or reads roots. It belongs here the day one of those appears, not before — a
|
|
36
|
+
* constant nothing emits reads as a check someone forgot to write.
|
|
37
|
+
*/
|
|
38
|
+
export const McpErrorCode = {
|
|
39
|
+
parse: -32700,
|
|
40
|
+
invalidRequest: -32600,
|
|
41
|
+
methodNotFound: -32601,
|
|
42
|
+
invalidParams: -32602,
|
|
43
|
+
internal: -32603,
|
|
44
|
+
headerMismatch: -32020,
|
|
45
|
+
unsupportedProtocolVersion: -32022,
|
|
46
|
+
} as const;
|
|
47
|
+
export type McpErrorCodeValue = (typeof McpErrorCode)[keyof typeof McpErrorCode];
|
|
48
|
+
|
|
49
|
+
export interface McpJsonRpcRequest {
|
|
50
|
+
jsonrpc: "2.0";
|
|
51
|
+
id?: string | number | null;
|
|
52
|
+
method?: string;
|
|
53
|
+
params?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface McpToolAnnotations {
|
|
57
|
+
readOnlyHint?: boolean;
|
|
58
|
+
destructiveHint?: boolean;
|
|
59
|
+
idempotentHint?: boolean;
|
|
60
|
+
openWorldHint?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface McpTool {
|
|
64
|
+
name: string;
|
|
65
|
+
title?: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
inputSchema: Record<string, unknown>;
|
|
68
|
+
outputSchema?: Record<string, unknown>;
|
|
69
|
+
annotations?: McpToolAnnotations;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface McpResourceTemplate {
|
|
73
|
+
uriTemplate: string;
|
|
74
|
+
name: string;
|
|
75
|
+
title?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
mimeType?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface McpResource {
|
|
81
|
+
uri: string;
|
|
82
|
+
name: string;
|
|
83
|
+
title?: string;
|
|
84
|
+
description?: string;
|
|
85
|
+
mimeType?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface McpPromptArgument {
|
|
89
|
+
name: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
required?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A prompt is user-controlled — the client offers it as a slash command and the model never invokes it — so its
|
|
96
|
+
* `title` and `description` are read by a person, not inferred from a schema the way a tool's are.
|
|
97
|
+
*/
|
|
98
|
+
export interface McpPrompt {
|
|
99
|
+
name: string;
|
|
100
|
+
title?: string;
|
|
101
|
+
description?: string;
|
|
102
|
+
arguments?: McpPromptArgument[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface McpTextContent {
|
|
106
|
+
type: "text";
|
|
107
|
+
text: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface McpToolResult {
|
|
111
|
+
content: McpTextContent[];
|
|
112
|
+
structuredContent?: unknown;
|
|
113
|
+
isError?: boolean;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface McpResourceContents {
|
|
117
|
+
uri: string;
|
|
118
|
+
mimeType: string;
|
|
119
|
+
text: string;
|
|
120
|
+
}
|
package/signal/middleware.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseEnv, Cls, PromiseOrObject } from "akanjs/base";
|
|
2
|
+
import { Logger } from "akanjs/common";
|
|
2
3
|
import { type CacheAdaptor, CacheAdaptorRole } from "akanjs/service";
|
|
3
4
|
import dayjs from "dayjs";
|
|
4
5
|
import type { SignalContext } from "./signalContext";
|
|
@@ -25,11 +26,14 @@ export class Logging extends middleware("logging") {
|
|
|
25
26
|
override async use() {
|
|
26
27
|
return async (context: SignalContext, next: () => Promise<unknown>) => {
|
|
27
28
|
const start = Date.now();
|
|
28
|
-
|
|
29
|
+
|
|
30
|
+
const debug = Logger.shouldLog("debug");
|
|
31
|
+
if (debug) context.adaptor.logger.debug(`Before ${context.endpointInfo.type}-${context.key} / ${start}`);
|
|
29
32
|
try {
|
|
30
33
|
const result = await next();
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
if (debug) {
|
|
35
|
+
context.adaptor.logger.debug(`After ${context.endpointInfo.type}-${context.key} / ${Date.now() - start}ms`);
|
|
36
|
+
}
|
|
33
37
|
return result;
|
|
34
38
|
} catch (error) {
|
|
35
39
|
const duration = Date.now() - start;
|