@wyrd-company/ahp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/src/errors.d.ts +28 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +39 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/provider-kit.d.ts +2 -0
- package/dist/src/provider-kit.d.ts.map +1 -0
- package/dist/src/provider-kit.js +2 -0
- package/dist/src/provider-kit.js.map +1 -0
- package/dist/src/resources.d.ts +22 -0
- package/dist/src/resources.d.ts.map +1 -0
- package/dist/src/resources.js +265 -0
- package/dist/src/resources.js.map +1 -0
- package/dist/src/server.d.ts +51 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +625 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/store.d.ts +36 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +132 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/transport/in-memory.d.ts +13 -0
- package/dist/src/transport/in-memory.d.ts.map +1 -0
- package/dist/src/transport/in-memory.js +18 -0
- package/dist/src/transport/in-memory.js.map +1 -0
- package/dist/src/types.d.ts +28 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wyrd Company
|
|
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,200 @@
|
|
|
1
|
+
# Agent Host Protocol (AHP) Server
|
|
2
|
+
|
|
3
|
+
Production-shaped TypeScript implementation of the
|
|
4
|
+
[Agent Host Protocol](https://github.com/microsoft/agent-host-protocol) server.
|
|
5
|
+
|
|
6
|
+
The package target is `@wyrd-company/ahp-server`.
|
|
7
|
+
|
|
8
|
+
## Current Scope
|
|
9
|
+
|
|
10
|
+
This repository contains the AHP server library core:
|
|
11
|
+
|
|
12
|
+
- A transport-agnostic AHP server core.
|
|
13
|
+
- Compatibility tests against the published `@microsoft/agent-host-protocol` TypeScript client.
|
|
14
|
+
- In-memory and filesystem-backed session stores behind a `SessionStore` interface.
|
|
15
|
+
- A pluggable `AgentProvider` interface for optional agent adapters.
|
|
16
|
+
- File-backed AHP `resource*` commands constrained to configured local roots.
|
|
17
|
+
- Transport adapters are provided by sibling packages, with TypeScript as the first implementation:
|
|
18
|
+
- `@wyrd-company/ahp-nats` for NATS.io JSON-RPC text frames.
|
|
19
|
+
- `@wyrd-company/ahp-grpc` for gRPC bidirectional streaming over Unix domain sockets.
|
|
20
|
+
- Optional provider adapters are published as sibling packages and are imported by host applications deliberately. Use `@wyrd-company/ahp-codex-app-server`, `@wyrd-company/ahp-claude-agent-sdk`, `@wyrd-company/ahp-cursor-sdk`, or `@wyrd-company/ahp-pi-agent` when wiring those runtimes.
|
|
21
|
+
|
|
22
|
+
The normal test suite validates the AHP client/server flow, multiple simultaneous client transports, active-client tool routing, resource commands, and session storage.
|
|
23
|
+
|
|
24
|
+
## Design Direction
|
|
25
|
+
|
|
26
|
+
The server is intended to be protocol-compliant with the Microsoft AHP TypeScript client as the compatibility tie-breaker. If protocol documentation and VS Code reference behavior disagree, this project follows the TypeScript client.
|
|
27
|
+
|
|
28
|
+
Adapters and transports are explicit packages. Users import optional packages and wire them into the server deliberately; runtime package discovery is not part of the first design. NATS and gRPC transports now live in sibling repos so their wire contracts can evolve toward multi-language implementations, with TypeScript as the initial implementation.
|
|
29
|
+
|
|
30
|
+
State can start in memory for tests and short-lived runs, or use `FileSystemSessionStore` to persist session state into a mounted directory across devcontainer rebuilds. Adapter runtime handles are intentionally not serialized; provider sessions are recreated by adapter/server wiring.
|
|
31
|
+
|
|
32
|
+
Security is scoped for local devcontainer/Docker-network use first. Remote and multi-tenant security are not implemented, but the transport and provider boundaries should not make that impossible later.
|
|
33
|
+
|
|
34
|
+
File resource commands only support `file://` URIs. They are constrained to `resourceRoots`. If no root is configured, the current process working directory is used. Existing targets are checked through `realpath` so symlinks cannot escape the allowed root.
|
|
35
|
+
|
|
36
|
+
## Implemented AHP Surface
|
|
37
|
+
|
|
38
|
+
The server currently implements the minimum useful session surface:
|
|
39
|
+
|
|
40
|
+
- `initialize`
|
|
41
|
+
- `ping`
|
|
42
|
+
- `reconnect` using snapshot fallback
|
|
43
|
+
- `subscribe`
|
|
44
|
+
- `unsubscribe`
|
|
45
|
+
- `listSessions`
|
|
46
|
+
- `resourceRead`
|
|
47
|
+
- `resourceWrite`
|
|
48
|
+
- `resourceList`
|
|
49
|
+
- `resourceCopy`
|
|
50
|
+
- `resourceDelete`
|
|
51
|
+
- `resourceMove`
|
|
52
|
+
- `resourceResolve`
|
|
53
|
+
- `resourceMkdir`
|
|
54
|
+
- `resolveSessionConfig`
|
|
55
|
+
- `createSession`
|
|
56
|
+
- `disposeSession`
|
|
57
|
+
- `fetchTurns`
|
|
58
|
+
- `completions`
|
|
59
|
+
- `dispatchAction`
|
|
60
|
+
|
|
61
|
+
`completions` currently returns an empty result. `resourceRequest` and `createResourceWatch` are not implemented yet.
|
|
62
|
+
|
|
63
|
+
Session output is streamed as AHP `action` notifications using:
|
|
64
|
+
|
|
65
|
+
- `session/responsePart`
|
|
66
|
+
- `session/delta`
|
|
67
|
+
- `session/turnComplete`
|
|
68
|
+
- `session/error`
|
|
69
|
+
|
|
70
|
+
Root session catalogue notifications are emitted for session add/remove/summary changes.
|
|
71
|
+
|
|
72
|
+
## Active-Client Tools
|
|
73
|
+
|
|
74
|
+
The server supports active-client tools as a provider-agnostic capability:
|
|
75
|
+
|
|
76
|
+
- `createSession.activeClient` seeds the provider session with the current active-client tool set.
|
|
77
|
+
- `session/activeClientToolsChanged` updates the provider session through the optional `AgentSession.setActiveClientTools` hook.
|
|
78
|
+
- Clearing the active client, disposing the session, or disconnecting the active client removes those tools from the provider session.
|
|
79
|
+
- Providers report active-client tool invocations through `AgentSessionContext.activeClientToolSink.reportInvocation`.
|
|
80
|
+
- The server emits `session/toolCallStart` and `session/toolCallReady` with `contributor: { kind: "client", clientId }`.
|
|
81
|
+
- `reportInvocation` resolves with the owning client's `session/toolCallComplete` result so provider runtimes can return tool output to their native tool-call flow.
|
|
82
|
+
- The server owns trusted correlation for session URI, turn id, tool call id, tool name, and owning client id. Tool input is not trusted for those fields.
|
|
83
|
+
- `session/toolCallComplete`, `session/toolCallContentChanged`, and `session/toolCallResultConfirmed` are accepted only from the active client that owns the server-recorded tool call.
|
|
84
|
+
- Optional provider packages map active-client tools to provider-specific tool surfaces, such as Streamable HTTP MCP or runtime-native tool APIs.
|
|
85
|
+
|
|
86
|
+
## Transport Packages
|
|
87
|
+
|
|
88
|
+
`@wyrd-company/ahp-server` does not include a CLI and does not re-export transport packages. Host applications import the transports they need and pass their `AhpTransport` instances to `AhpServer.accept(...)`.
|
|
89
|
+
|
|
90
|
+
The NATS transport package uses this subject convention:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
<namespace>.server.<serverId>.client.<clientId>.to-server
|
|
94
|
+
<namespace>.server.<serverId>.client.<clientId>.to-client
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The default namespace is `ahp`. Subject tokens are sanitized to NATS-safe token text by `@wyrd-company/ahp-nats`.
|
|
98
|
+
|
|
99
|
+
The gRPC transport package exposes one bidirectional streaming RPC over a Unix domain socket:
|
|
100
|
+
|
|
101
|
+
```protobuf
|
|
102
|
+
service AhpTransport {
|
|
103
|
+
rpc Connect(stream AhpFrame) returns (stream AhpFrame);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
message AhpFrame {
|
|
107
|
+
string text = 1;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Each `text` value is one UTF-8 JSON-RPC AHP frame. The canonical proto lives in `@wyrd-company/ahp-grpc` under `proto/wyrd/ahp/transport/v1/transport.proto`.
|
|
112
|
+
|
|
113
|
+
## Usage Sketch
|
|
114
|
+
|
|
115
|
+
### User-Owned Host
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import {
|
|
119
|
+
AhpServer,
|
|
120
|
+
FileSystemSessionStore,
|
|
121
|
+
createInProcessAhpClientTransport,
|
|
122
|
+
} from '@wyrd-company/ahp-server';
|
|
123
|
+
import { createClaudeAgentSdkProvider } from '@wyrd-company/ahp-claude-agent-sdk';
|
|
124
|
+
import { createPiCodingAgentProvider } from '@wyrd-company/ahp-pi-agent';
|
|
125
|
+
import {
|
|
126
|
+
createNatsServerTransport,
|
|
127
|
+
ahpNatsSubjects,
|
|
128
|
+
} from '@wyrd-company/ahp-nats';
|
|
129
|
+
import {
|
|
130
|
+
createGrpcUdsServer,
|
|
131
|
+
} from '@wyrd-company/ahp-grpc';
|
|
132
|
+
import { connect } from '@nats-io/transport-node';
|
|
133
|
+
|
|
134
|
+
const natsConnection = await connect({ servers: process.env.NATS_URL });
|
|
135
|
+
|
|
136
|
+
const subjects = ahpNatsSubjects({
|
|
137
|
+
serverId: 'devcontainer-1',
|
|
138
|
+
clientId: 'client-1',
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const server = new AhpServer({
|
|
142
|
+
store: new FileSystemSessionStore({
|
|
143
|
+
directory: '/workspace-storage/ahp-server',
|
|
144
|
+
}),
|
|
145
|
+
defaultDirectory: 'file:///workspace',
|
|
146
|
+
resourceRoots: ['file:///workspace'],
|
|
147
|
+
providers: [
|
|
148
|
+
createPiCodingAgentProvider(),
|
|
149
|
+
createClaudeAgentSdkProvider({
|
|
150
|
+
defaultModel: 'claude-sonnet-4-6',
|
|
151
|
+
permissionMode: 'dontAsk',
|
|
152
|
+
}),
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
await server.accept(createNatsServerTransport({
|
|
157
|
+
connection: natsConnection,
|
|
158
|
+
inboundSubject: subjects.clientToServer,
|
|
159
|
+
outboundSubject: subjects.serverToClient,
|
|
160
|
+
}));
|
|
161
|
+
|
|
162
|
+
const grpcServer = createGrpcUdsServer({
|
|
163
|
+
socketPath: '/tmp/ahp-server/ahp.sock',
|
|
164
|
+
onTransport: transport => {
|
|
165
|
+
void server.accept(transport);
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
await grpcServer.listen();
|
|
169
|
+
|
|
170
|
+
const inProcess = createInProcessAhpClientTransport(server);
|
|
171
|
+
|
|
172
|
+
// Pass `inProcess.transport` to an in-process AHP client, such as an A2A
|
|
173
|
+
// adapter running in the same host process. The application still owns the
|
|
174
|
+
// server, providers, and external AHP transports.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npm install
|
|
181
|
+
npm run verify
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`npm run verify` runs:
|
|
185
|
+
|
|
186
|
+
- TypeScript typecheck
|
|
187
|
+
- Node test suite
|
|
188
|
+
- Build
|
|
189
|
+
|
|
190
|
+
## References
|
|
191
|
+
|
|
192
|
+
- AHP protocol and TypeScript client: `/workspaces/references/agent-host-protocol`
|
|
193
|
+
- VS Code reference AHP server: `/workspaces/references/vscode/src/vs/platform/agentHost/node`
|
|
194
|
+
- Pi Agent harness: `/workspaces/references/pi`
|
|
195
|
+
- Claude Agent SDK: `/workspaces/references/claude-agent-sdk-typescript`
|
|
196
|
+
|
|
197
|
+
## Planned Follow-Up
|
|
198
|
+
|
|
199
|
+
- Remove the temporary `./provider-kit` compatibility re-export once consumers import `@wyrd-company/ahp-provider-kit` directly.
|
|
200
|
+
- Create a separate reference host or CLI package if a reusable executable becomes useful.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface JsonRpcErrorObject {
|
|
2
|
+
readonly code: number;
|
|
3
|
+
readonly message: string;
|
|
4
|
+
readonly data?: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare const JsonRpcErrorCodes: {
|
|
7
|
+
readonly ParseError: -32700;
|
|
8
|
+
readonly InvalidRequest: -32600;
|
|
9
|
+
readonly MethodNotFound: -32601;
|
|
10
|
+
readonly InvalidParams: -32602;
|
|
11
|
+
readonly InternalError: -32603;
|
|
12
|
+
readonly ProviderNotFound: -32002;
|
|
13
|
+
readonly SessionAlreadyExists: -32003;
|
|
14
|
+
readonly UnsupportedProtocolVersion: -32005;
|
|
15
|
+
readonly NotFound: -32008;
|
|
16
|
+
readonly PermissionDenied: -32009;
|
|
17
|
+
readonly AlreadyExists: -32010;
|
|
18
|
+
readonly Conflict: -32011;
|
|
19
|
+
};
|
|
20
|
+
export declare class AhpServerError extends Error {
|
|
21
|
+
readonly code: number;
|
|
22
|
+
readonly data?: unknown;
|
|
23
|
+
constructor(code: number, message: string, data?: unknown);
|
|
24
|
+
toJsonRpcError(): JsonRpcErrorObject;
|
|
25
|
+
}
|
|
26
|
+
export declare function toJsonRpcError(error: unknown): JsonRpcErrorObject;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAapB,CAAC;AAEX,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAOzD,cAAc,IAAI,kBAAkB;CAKrC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAQjE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const JsonRpcErrorCodes = {
|
|
2
|
+
ParseError: -32700,
|
|
3
|
+
InvalidRequest: -32600,
|
|
4
|
+
MethodNotFound: -32601,
|
|
5
|
+
InvalidParams: -32602,
|
|
6
|
+
InternalError: -32603,
|
|
7
|
+
ProviderNotFound: -32002,
|
|
8
|
+
SessionAlreadyExists: -32003,
|
|
9
|
+
UnsupportedProtocolVersion: -32005,
|
|
10
|
+
NotFound: -32008,
|
|
11
|
+
PermissionDenied: -32009,
|
|
12
|
+
AlreadyExists: -32010,
|
|
13
|
+
Conflict: -32011,
|
|
14
|
+
};
|
|
15
|
+
export class AhpServerError extends Error {
|
|
16
|
+
code;
|
|
17
|
+
data;
|
|
18
|
+
constructor(code, message, data) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = 'AhpServerError';
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.data = data;
|
|
23
|
+
}
|
|
24
|
+
toJsonRpcError() {
|
|
25
|
+
return this.data === undefined
|
|
26
|
+
? { code: this.code, message: this.message }
|
|
27
|
+
: { code: this.code, message: this.message, data: this.data };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function toJsonRpcError(error) {
|
|
31
|
+
if (error instanceof AhpServerError) {
|
|
32
|
+
return error.toJsonRpcError();
|
|
33
|
+
}
|
|
34
|
+
if (error instanceof Error) {
|
|
35
|
+
return { code: JsonRpcErrorCodes.InternalError, message: error.message };
|
|
36
|
+
}
|
|
37
|
+
return { code: JsonRpcErrorCodes.InternalError, message: String(error) };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,UAAU,EAAE,CAAC,KAAK;IAClB,cAAc,EAAE,CAAC,KAAK;IACtB,cAAc,EAAE,CAAC,KAAK;IACtB,aAAa,EAAE,CAAC,KAAK;IACrB,aAAa,EAAE,CAAC,KAAK;IACrB,gBAAgB,EAAE,CAAC,KAAK;IACxB,oBAAoB,EAAE,CAAC,KAAK;IAC5B,0BAA0B,EAAE,CAAC,KAAK;IAClC,QAAQ,EAAE,CAAC,KAAK;IAChB,gBAAgB,EAAE,CAAC,KAAK;IACxB,aAAa,EAAE,CAAC,KAAK;IACrB,QAAQ,EAAE,CAAC,KAAK;CACR,CAAC;AAEX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAAS;IACb,IAAI,CAAW;IAExB,YAAY,IAAY,EAAE,OAAe,EAAE,IAAc;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;YAC5B,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;YAC5C,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,cAAc,EAAE,CAAC;IAChC,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,iBAAiB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { AhpServer } from './server.js';
|
|
2
|
+
export { ActiveClientToolRouter, MarkdownTurnEmitter, markdownPart, markdownPartId, resolveModelId, singleModelAgentInfo, stringOrMarkdown, uriToPath, } from './provider-kit.js';
|
|
3
|
+
export { FileSystemSessionStore, InMemorySessionStore } from './store.js';
|
|
4
|
+
export { InMemoryServerTransport, createInMemoryTransportPair, createInProcessAhpClientTransport, } from './transport/in-memory.js';
|
|
5
|
+
export type { ActiveClientToolRouterInvocation, ActiveClientToolRouterOptions, SingleModelAgentInfoOptions, } from './provider-kit.js';
|
|
6
|
+
export type { ActiveClientToolInvocation, ActiveClientTools, ActiveClientToolSink, AhpTransport, AgentProvider, AgentSession, AgentSessionContext, AgentTurnSink, AhpServerOptions, JsonRpcErrorResponse, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse, ServerTransport, SessionStore, TransportFrame, } from './types.js';
|
|
7
|
+
export type { FileSystemSessionStoreOptions } from './store.js';
|
|
8
|
+
export type { InProcessAhpClientTransport, ReusableAhpServer, } from './transport/in-memory.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,gCAAgC,EAChC,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAChE,YAAY,EACV,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AhpServer } from './server.js';
|
|
2
|
+
export { ActiveClientToolRouter, MarkdownTurnEmitter, markdownPart, markdownPartId, resolveModelId, singleModelAgentInfo, stringOrMarkdown, uriToPath, } from './provider-kit.js';
|
|
3
|
+
export { FileSystemSessionStore, InMemorySessionStore } from './store.js';
|
|
4
|
+
export { InMemoryServerTransport, createInMemoryTransportPair, createInProcessAhpClientTransport, } from './transport/in-memory.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-kit.d.ts","sourceRoot":"","sources":["../../src/provider-kit.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-kit.js","sourceRoot":"","sources":["../../src/provider-kit.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ResourceCopyParams, type ResourceCopyResult, type ResourceDeleteParams, type ResourceDeleteResult, type ResourceListParams, type ResourceListResult, type ResourceMkdirParams, type ResourceMkdirResult, type ResourceMoveParams, type ResourceMoveResult, type ResourceReadParams, type ResourceReadResult, type ResourceResolveParams, type ResourceResolveResult, type ResourceWriteParams, type ResourceWriteResult, type URI } from '@microsoft/agent-host-protocol';
|
|
2
|
+
export interface FileResourceServiceOptions {
|
|
3
|
+
readonly roots?: readonly URI[];
|
|
4
|
+
}
|
|
5
|
+
export declare class FileResourceService {
|
|
6
|
+
private readonly roots;
|
|
7
|
+
constructor(options?: FileResourceServiceOptions);
|
|
8
|
+
read(params: ResourceReadParams): Promise<ResourceReadResult>;
|
|
9
|
+
write(params: ResourceWriteParams): Promise<ResourceWriteResult>;
|
|
10
|
+
list(params: ResourceListParams): Promise<ResourceListResult>;
|
|
11
|
+
copy(params: ResourceCopyParams): Promise<ResourceCopyResult>;
|
|
12
|
+
delete(params: ResourceDeleteParams): Promise<ResourceDeleteResult>;
|
|
13
|
+
move(params: ResourceMoveParams): Promise<ResourceMoveResult>;
|
|
14
|
+
resolve(params: ResourceResolveParams): Promise<ResourceResolveResult>;
|
|
15
|
+
mkdir(params: ResourceMkdirParams): Promise<ResourceMkdirResult>;
|
|
16
|
+
private resolveExisting;
|
|
17
|
+
private resolveWritable;
|
|
18
|
+
private assertNearestExistingParentAllowed;
|
|
19
|
+
private resolveAllowedPath;
|
|
20
|
+
private assertAllowedPath;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/resources.ts"],"names":[],"mappings":"AAiBA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAE1B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAExB,KAAK,GAAG,EACT,MAAM,gCAAgC,CAAC;AAIxC,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC;CACjC;AAID,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;gBAErB,OAAO,GAAE,0BAA+B;IAK9C,IAAI,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAW7D,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAmChE,IAAI,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAe7D,IAAI,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAe7D,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMnE,IAAI,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAa7D,OAAO,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAmBtE,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAcxD,eAAe;YAWf,eAAe;YAgBf,kCAAkC;IAgBhD,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;CAO1B"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { constants as fsConstants, copyFile, cp, lstat, mkdir, readdir, readFile, realpath, rename, rm, stat, writeFile, } from 'node:fs/promises';
|
|
2
|
+
import { dirname, extname, isAbsolute, normalize, relative, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
4
|
+
import { AhpServerError, JsonRpcErrorCodes } from './errors.js';
|
|
5
|
+
export class FileResourceService {
|
|
6
|
+
roots;
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
const configuredRoots = options.roots?.length ? options.roots : [`file://${process.cwd()}`];
|
|
9
|
+
this.roots = configuredRoots.map(root => normalizePath(uriToPath(root)));
|
|
10
|
+
}
|
|
11
|
+
async read(params) {
|
|
12
|
+
const path = await this.resolveExisting(params.uri);
|
|
13
|
+
const data = await readFile(path);
|
|
14
|
+
const encoding = (params.encoding ?? 'utf-8');
|
|
15
|
+
return {
|
|
16
|
+
data: encoding === 'base64' ? data.toString('base64') : data.toString('utf8'),
|
|
17
|
+
encoding: encoding,
|
|
18
|
+
contentType: contentType(path, encoding),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async write(params) {
|
|
22
|
+
const path = await this.resolveWritable(params.uri);
|
|
23
|
+
const payload = decodeData(params.data, params.encoding);
|
|
24
|
+
const exists = await pathExists(path);
|
|
25
|
+
if (params.createOnly && exists) {
|
|
26
|
+
throw new AhpServerError(JsonRpcErrorCodes.AlreadyExists, `resource already exists: ${params.uri}`);
|
|
27
|
+
}
|
|
28
|
+
if (params.ifMatch) {
|
|
29
|
+
if (!exists) {
|
|
30
|
+
throw new AhpServerError(JsonRpcErrorCodes.Conflict, `resource etag does not match: ${params.uri}`);
|
|
31
|
+
}
|
|
32
|
+
const current = await stat(path);
|
|
33
|
+
if (etag(current) !== params.ifMatch) {
|
|
34
|
+
throw new AhpServerError(JsonRpcErrorCodes.Conflict, `resource etag does not match: ${params.uri}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let output;
|
|
38
|
+
const mode = params.mode ?? 'truncate';
|
|
39
|
+
const position = params.position ?? 0;
|
|
40
|
+
if (mode === 'truncate') {
|
|
41
|
+
const existing = exists ? await readFile(path) : Buffer.alloc(0);
|
|
42
|
+
output = Buffer.concat([existing.subarray(0, clamp(position, 0, existing.length)), payload]);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const existing = exists ? await readFile(path) : Buffer.alloc(0);
|
|
46
|
+
const insertAt = mode === 'append'
|
|
47
|
+
? clamp(existing.length - position, 0, existing.length)
|
|
48
|
+
: clamp(position, 0, existing.length);
|
|
49
|
+
output = Buffer.concat([existing.subarray(0, insertAt), payload, existing.subarray(insertAt)]);
|
|
50
|
+
}
|
|
51
|
+
await writeFile(path, output, { mode: 0o600 });
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
async list(params) {
|
|
55
|
+
const path = await this.resolveExisting(params.uri);
|
|
56
|
+
const entries = await readdir(path, { withFileTypes: true }).catch(error => {
|
|
57
|
+
throw mapFsError(error, `resource is not a directory: ${params.uri}`);
|
|
58
|
+
});
|
|
59
|
+
const result = entries
|
|
60
|
+
.filter(entry => entry.isFile() || entry.isDirectory())
|
|
61
|
+
.map(entry => ({
|
|
62
|
+
name: entry.name,
|
|
63
|
+
type: entry.isDirectory() ? 'directory' : 'file',
|
|
64
|
+
}))
|
|
65
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
66
|
+
return { entries: result };
|
|
67
|
+
}
|
|
68
|
+
async copy(params) {
|
|
69
|
+
const source = await this.resolveExisting(params.source);
|
|
70
|
+
const destination = await this.resolveWritable(params.destination);
|
|
71
|
+
if (params.failIfExists && await pathExists(destination)) {
|
|
72
|
+
throw new AhpServerError(JsonRpcErrorCodes.AlreadyExists, `resource already exists: ${params.destination}`);
|
|
73
|
+
}
|
|
74
|
+
const sourceStat = await stat(source);
|
|
75
|
+
if (sourceStat.isDirectory()) {
|
|
76
|
+
await cp(source, destination, { recursive: true, force: !params.failIfExists, errorOnExist: params.failIfExists });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
await copyFile(source, destination, params.failIfExists ? fsConstants.COPYFILE_EXCL : 0);
|
|
80
|
+
}
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
async delete(params) {
|
|
84
|
+
const path = await this.resolveExisting(params.uri);
|
|
85
|
+
await rm(path, { recursive: params.recursive ?? false });
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
async move(params) {
|
|
89
|
+
const source = await this.resolveExisting(params.source);
|
|
90
|
+
const destination = await this.resolveWritable(params.destination);
|
|
91
|
+
if (params.failIfExists && await pathExists(destination)) {
|
|
92
|
+
throw new AhpServerError(JsonRpcErrorCodes.AlreadyExists, `resource already exists: ${params.destination}`);
|
|
93
|
+
}
|
|
94
|
+
if (!params.failIfExists && await pathExists(destination)) {
|
|
95
|
+
await rm(destination, { recursive: true, force: true });
|
|
96
|
+
}
|
|
97
|
+
await rename(source, destination);
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
async resolve(params) {
|
|
101
|
+
const path = params.followSymlinks === false
|
|
102
|
+
? this.resolveAllowedPath(params.uri)
|
|
103
|
+
: await this.resolveExisting(params.uri);
|
|
104
|
+
const stats = params.followSymlinks === false ? await lstat(path) : await stat(path);
|
|
105
|
+
if (params.followSymlinks === false && stats.isSymbolicLink()) {
|
|
106
|
+
this.assertAllowedPath(path);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
uri: pathToFileURL(path).href,
|
|
110
|
+
type: resourceType(stats),
|
|
111
|
+
...(stats.isDirectory() ? {} : { size: stats.size }),
|
|
112
|
+
mtime: stats.mtime.toISOString(),
|
|
113
|
+
ctime: stats.ctime.toISOString(),
|
|
114
|
+
...(stats.isFile() ? { contentType: contentType(path, 'base64') } : {}),
|
|
115
|
+
etag: etag(stats),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async mkdir(params) {
|
|
119
|
+
const path = this.resolveAllowedPath(params.uri);
|
|
120
|
+
await this.assertNearestExistingParentAllowed(path);
|
|
121
|
+
if (await pathExists(path)) {
|
|
122
|
+
const stats = await stat(path);
|
|
123
|
+
if (!stats.isDirectory()) {
|
|
124
|
+
throw new AhpServerError(JsonRpcErrorCodes.AlreadyExists, `resource already exists and is not a directory: ${params.uri}`);
|
|
125
|
+
}
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
await mkdir(path, { recursive: true, mode: 0o700 });
|
|
129
|
+
return {};
|
|
130
|
+
}
|
|
131
|
+
async resolveExisting(uri) {
|
|
132
|
+
const requested = this.resolveAllowedPath(uri);
|
|
133
|
+
try {
|
|
134
|
+
const canonical = await realpath(requested);
|
|
135
|
+
this.assertAllowedPath(canonical);
|
|
136
|
+
return canonical;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw mapFsError(error, `resource not found: ${uri}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async resolveWritable(uri) {
|
|
143
|
+
const requested = this.resolveAllowedPath(uri);
|
|
144
|
+
const parent = dirname(requested);
|
|
145
|
+
try {
|
|
146
|
+
const canonicalParent = await realpath(parent);
|
|
147
|
+
this.assertAllowedPath(canonicalParent);
|
|
148
|
+
if (await pathExists(requested)) {
|
|
149
|
+
const canonicalTarget = await realpath(requested);
|
|
150
|
+
this.assertAllowedPath(canonicalTarget);
|
|
151
|
+
}
|
|
152
|
+
return requested;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw mapFsError(error, `resource parent not found: ${uri}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async assertNearestExistingParentAllowed(path) {
|
|
159
|
+
let current = dirname(path);
|
|
160
|
+
while (true) {
|
|
161
|
+
if (await pathExists(current)) {
|
|
162
|
+
const canonical = await realpath(current);
|
|
163
|
+
this.assertAllowedPath(canonical);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const parent = dirname(current);
|
|
167
|
+
if (parent === current) {
|
|
168
|
+
throw new AhpServerError(JsonRpcErrorCodes.NotFound, `resource parent not found: ${path}`);
|
|
169
|
+
}
|
|
170
|
+
current = parent;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
resolveAllowedPath(uri) {
|
|
174
|
+
const path = normalizePath(uriToPath(uri));
|
|
175
|
+
this.assertAllowedPath(path);
|
|
176
|
+
return path;
|
|
177
|
+
}
|
|
178
|
+
assertAllowedPath(path) {
|
|
179
|
+
const normalized = normalizePath(path);
|
|
180
|
+
if (this.roots.some(root => normalized === root || relative(root, normalized).startsWith('..') === false && !isAbsolute(relative(root, normalized)))) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
throw new AhpServerError(JsonRpcErrorCodes.PermissionDenied, `resource is outside allowed roots: ${path}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function uriToPath(uri) {
|
|
187
|
+
if (!uri.startsWith('file://')) {
|
|
188
|
+
throw new AhpServerError(JsonRpcErrorCodes.PermissionDenied, `unsupported resource URI scheme: ${uri}`);
|
|
189
|
+
}
|
|
190
|
+
return fileURLToPath(uri);
|
|
191
|
+
}
|
|
192
|
+
function normalizePath(path) {
|
|
193
|
+
return normalize(resolve(path));
|
|
194
|
+
}
|
|
195
|
+
function decodeData(data, encoding) {
|
|
196
|
+
if (encoding === 'base64') {
|
|
197
|
+
return Buffer.from(data, 'base64');
|
|
198
|
+
}
|
|
199
|
+
if (encoding === 'utf-8') {
|
|
200
|
+
return Buffer.from(data, 'utf8');
|
|
201
|
+
}
|
|
202
|
+
throw new AhpServerError(JsonRpcErrorCodes.InvalidParams, `unsupported resource encoding: ${encoding}`);
|
|
203
|
+
}
|
|
204
|
+
function contentType(path, encoding) {
|
|
205
|
+
const ext = extname(path).toLowerCase();
|
|
206
|
+
if (ext === '.json') {
|
|
207
|
+
return 'application/json';
|
|
208
|
+
}
|
|
209
|
+
if (ext === '.md') {
|
|
210
|
+
return 'text/markdown';
|
|
211
|
+
}
|
|
212
|
+
if (ext === '.txt' || encoding === 'utf-8') {
|
|
213
|
+
return 'text/plain';
|
|
214
|
+
}
|
|
215
|
+
return 'application/octet-stream';
|
|
216
|
+
}
|
|
217
|
+
function resourceType(stats) {
|
|
218
|
+
if (stats.isFile()) {
|
|
219
|
+
return 'file';
|
|
220
|
+
}
|
|
221
|
+
if (stats.isDirectory()) {
|
|
222
|
+
return 'directory';
|
|
223
|
+
}
|
|
224
|
+
if (stats.isSymbolicLink()) {
|
|
225
|
+
return 'symlink';
|
|
226
|
+
}
|
|
227
|
+
return 'file';
|
|
228
|
+
}
|
|
229
|
+
function etag(stats) {
|
|
230
|
+
return `W/"${stats.size}-${Math.trunc(stats.mtimeMs)}"`;
|
|
231
|
+
}
|
|
232
|
+
async function pathExists(path) {
|
|
233
|
+
try {
|
|
234
|
+
await lstat(path);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
if (isNodeError(error) && error.code === 'ENOENT') {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function mapFsError(error, fallback) {
|
|
245
|
+
if (!isNodeError(error)) {
|
|
246
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
247
|
+
}
|
|
248
|
+
if (error.code === 'ENOENT' || error.code === 'ENOTDIR') {
|
|
249
|
+
return new AhpServerError(JsonRpcErrorCodes.NotFound, fallback);
|
|
250
|
+
}
|
|
251
|
+
if (error.code === 'EEXIST') {
|
|
252
|
+
return new AhpServerError(JsonRpcErrorCodes.AlreadyExists, fallback);
|
|
253
|
+
}
|
|
254
|
+
if (error.code === 'EACCES' || error.code === 'EPERM') {
|
|
255
|
+
return new AhpServerError(JsonRpcErrorCodes.PermissionDenied, fallback);
|
|
256
|
+
}
|
|
257
|
+
return new AhpServerError(JsonRpcErrorCodes.InternalError, error.message);
|
|
258
|
+
}
|
|
259
|
+
function isNodeError(error) {
|
|
260
|
+
return error instanceof Error && 'code' in error;
|
|
261
|
+
}
|
|
262
|
+
function clamp(value, min, max) {
|
|
263
|
+
return Math.min(Math.max(value, min), max);
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/resources.ts"],"names":[],"mappings":"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"}
|