refactor: apply repository naming contract
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/api/README.md
|
||||
README.md: 7c75e8012459266e0ce09c97416d140e5ac777e1
|
||||
README.zh.md: f4e882570d2dc929cca466e0bdb05bb2943f2c93
|
||||
README.md: 2db5c518f75a1bba5790146a5f1b91a4fa5bf745
|
||||
README.zh.md: 1fc41ee43c184054a558e6fa8ebe7de0e87530b6
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The application-facing Remote stack. `remotes` owns BFF policy and the selected business API, while `gateway` implements the TypeRT unary RPC endpoints shared by Host and Client environments.
|
||||
The application-facing Remote stack. `remotes` owns BFF policy and the selected business API, while `gateway` implements the Typert unary RPC endpoints shared by Host and Client environments.
|
||||
|
||||
| Package | Role | ctx key |
|
||||
|---|---|---|
|
||||
| [`remotes/`](remotes/README.md) | Host Agent/Session lookup policy and Client Remote contribution assembly | no service; configures `ctx.typert` and consumes `ctx.remote` |
|
||||
| [`gateway/`](gateway/README.md) | Host TypeRT dispatcher and Client Remote endpoint | `ctx.typertGateway` / `ctx.remote` |
|
||||
| [`gateway/`](gateway/README.md) | Host Typert dispatcher and Client Remote endpoint | `ctx.typertGateway` / `ctx.remote` |
|
||||
|
||||
The runtime dependency direction is `remotes → gateway → connection → webserver`: the BFF consumes the shared `TypeRTClientRemote` contract, Gateway delegates transport to Connection, and Connection mounts on the HTTP server. Cordis service injection and Client module metadata preserve this order without importing the concrete Gateway from the Remotes Client entry.
|
||||
The runtime dependency direction is `remotes → gateway → connection → webserver`: the BFF consumes the shared `TypertClientRemote` contract, Gateway delegates transport to Connection, and Connection mounts on the HTTP server. Cordis service injection and Client module metadata preserve this order without importing the concrete Gateway from the Remotes Client entry.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
面向应用的 Remote 技术栈。`remotes` 负责 BFF 策略和选定的业务 API,`gateway` 则实现 Host 与 Client 环境共用的 TypeRT 一元 RPC endpoint。
|
||||
面向应用的 Remote 技术栈。`remotes` 负责 BFF 策略和选定的业务 API,`gateway` 则实现 Host 与 Client 环境共用的 Typert 一元 RPC endpoint。
|
||||
|
||||
| 包 | 职责 | ctx key |
|
||||
|---|---|---|
|
||||
| [`remotes/`](remotes/README.md) | Host Agent/Session lookup 策略与 Client Remote contribution 装配 | 无服务;配置 `ctx.typert` 并消费 `ctx.remote` |
|
||||
| [`gateway/`](gateway/README.md) | Host TypeRT 分发器与 Client Remote endpoint | `ctx.typertGateway` / `ctx.remote` |
|
||||
| [`gateway/`](gateway/README.md) | Host Typert 分发器与 Client Remote endpoint | `ctx.typertGateway` / `ctx.remote` |
|
||||
|
||||
运行时依赖方向为 `remotes → gateway → connection → webserver`:BFF 消费共享的 `TypeRTClientRemote` 约定,Gateway 把传输交给 Connection,Connection 再挂载到 HTTP server。Cordis 服务注入与 Client 模块元数据在不让 Remotes Client 入口导入具体 Gateway 实现的前提下维持该顺序。
|
||||
运行时依赖方向为 `remotes → gateway → connection → webserver`:BFF 消费共享的 `TypertClientRemote` 约定,Gateway 把传输交给 Connection,Connection 再挂载到 HTTP server。Cordis 服务注入与 Client 模块元数据在不让 Remotes Client 入口导入具体 Gateway 实现的前提下维持该顺序。
|
||||
|
||||
## 已知限制与延期工作
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/api/gateway/README.md
|
||||
README.md: 96f55eead6aec50e2f39f5bcefe71b51cc853298
|
||||
README.zh.md: 8985fd1f57833bc05f045e72135bb69a5a198d50
|
||||
README.md: 7caf707c376bd3e2654fad1f0c01ac83e6faa44c
|
||||
README.zh.md: b340df982ed1ca9b980fbcf60729d8124319ce6e
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Two-sided TypeRT RPC endpoint for Host and Client Cordis environments. The Host entry provides `ctx.typertGateway`, while `@deepseek-ai/dsh-api-gateway/client` provides `ctx.remote`; both consume the same generated `InvocationDescriptor` contract and leave business selection to API Remotes and transport, request correlation, trust, and response envelopes to Connection.
|
||||
Two-sided Typert RPC endpoint for Host and Client Cordis environments. The Host entry provides `ctx.typertGateway`, while `@deepseek-ai/dsh-api-gateway/client` provides `ctx.remote`; both consume the same generated `InvocationDescriptor` contract and leave business selection to API Remotes and transport, request correlation, trust, and response envelopes to Connection.
|
||||
|
||||
## Host service: `TypertGatewayService` (ctx key: `typertGateway`)
|
||||
|
||||
`ctx.typertGateway.invoke()` resolves the current descriptor and Cordis Service for each call, validates exact named arguments, resolves registered object or Context identities, invokes the public business method, and validates its result. Business Services extend `GatewayService` and mark methods with `@Remote` or `@RemoteScope` from [`dsh-type-meta`](../../typert/type-meta/README.md); `bindTypeRTGateway()` remains available when another base class owns inheritance.
|
||||
`ctx.typertGateway.invoke()` resolves the current descriptor and Cordis Service for each call, validates exact named arguments, resolves registered object or Context identities, invokes the public business method, and validates its result. Business Services extend `TypertRemoteService` and mark methods with `@Remote` or `@RemoteScope` from [`dsh-typert-protocol`](../../typert/protocol/README.md); `bindTypertRemote()` remains available when another base class owns inheritance.
|
||||
|
||||
Strict mode reads generated invocation descriptors from `ctx.typert.local`. Lookup parameters use the currently active resolver in `ctx.typert.lookups`: the business package registers the stable declaration and default policy, while Host composition can override resolution behavior with effect-scoped `configure()`; `@RemoteScope` resolves its receiver through a registered Host Context provider. SRC mode is a development fallback for endpoints that have never had a strict definition; it parses simple parameter names and accepts only JSON-safe values for non-lookup parameters. Withdrawing an observed strict definition fails instead of weakening validation.
|
||||
|
||||
The Host entry registers a trusted-host interceptor on Connection's shared `/api` FetchHandler. Connection passes this composite handler through its HTTP bridge; the handler dispatches claimed endpoints to Gateway and unclaimed endpoints to API Proxy. Direct `invoke()` calls preserve business errors; `TypertGatewayError` distinguishes failures owned by dispatch, binding, providers, lookup, Context, arguments, and codecs. A resolver may use `TypeRTLookupFailure` to carry an existing RPC error, preserving its original error code for policy rejections such as cold-resume failures or ownership fences.
|
||||
The Host entry registers a trusted-host interceptor on Connection's shared `/api` FetchHandler. Connection passes this composite handler through its HTTP bridge; the handler dispatches claimed endpoints to Gateway and unclaimed endpoints to API Proxy. Direct `invoke()` calls preserve business errors; `TypertGatewayError` distinguishes failures owned by dispatch, binding, providers, lookup, Context, arguments, and codecs. A resolver may use `TypertLookupFailure` to carry an existing RPC error, preserving its original error code for policy rejections such as cold-resume failures or ownership fences.
|
||||
|
||||
A cancellation-aware Remote method declares `signal: AbortSignal` as its final Host parameter. The signal is descriptor metadata rather than a wire argument: Connection supplies it to the Gateway, and the Gateway injects it after decoded business parameters. SRC recognizes the reserved final name, while strict generation additionally requires the global `AbortSignal` type.
|
||||
|
||||
@@ -22,7 +22,7 @@ Each call validates positional inputs, constructs the descriptor's exact named `
|
||||
|
||||
`ctx.remote.$on()` subscribes to one forwarded Host event. Its legal keys are exactly the Host assembly's forwarding selection, and the listener type is the owning package's own Cordis `Events` declaration, so no second signature can drift from it. Each subscription belongs to the calling fiber and disappears with it. Delivery is one-way and follows registration order; a listener that throws is logged and isolated from the remaining listeners, which never affects the frame pump. `ctx.remote.$dispatch()` is the other half of that surface, and it is the carrier's: the Client half owning the Host frame sink hands each decoded frame over, and an event name nobody subscribes to is dropped, since the wire carries whatever the Host selected. A consumer subscribes and never calls it.
|
||||
|
||||
Generated declaration merges provide the TypeScript API through the shared `TypeRTClientRemote` contract. The Client entry contains no Host Service or Host Cordis interface merge, and method lookup and invocation use ordinary objects and functions rather than a JavaScript Proxy.
|
||||
Generated declaration merges provide the TypeScript API through the shared `TypertClientRemote` contract. The Client entry contains no Host Service or Host Cordis interface merge, and method lookup and invocation use ordinary objects and functions rather than a JavaScript Proxy.
|
||||
|
||||
## Model Experience
|
||||
|
||||
@@ -34,7 +34,7 @@ No direct effect; invoked business Services own any model-visible result.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- The Connection adapter maps ordinary dispatch failures and business exceptions to the RPC `internal` code with empty details; lookup-policy errors carried by `TypeRTLookupFailure` are returned unchanged. Structured `TypertGatewayError` categories remain available only to same-process callers.
|
||||
- The Connection adapter maps ordinary dispatch failures and business exceptions to the RPC `internal` code with empty details; lookup-policy errors carried by `TypertLookupFailure` are returned unchanged. Structured `TypertGatewayError` categories remain available only to same-process callers.
|
||||
- SRC mode supports unique identifier parameters without destructuring, defaults, or rest parameters. It validates JSON safety rather than generated business types and never infers optional fields.
|
||||
- Only strict generated contributions can mount on the Client face. SRC markers have no Client codec or type projection.
|
||||
- The package dispatches unary methods only. Incremental Session data uses a separate named-stream protocol over the same Connection.
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
为 Host 与 Client 两侧的 Cordis 环境提供 TypeRT RPC endpoint。Host 入口提供 `ctx.typertGateway`,`@deepseek-ai/dsh-api-gateway/client` 则提供 `ctx.remote`;两者使用同一份生成的 `InvocationDescriptor` 约定,并将业务选择交给 API Remotes,将传输、请求关联、信任和响应封装交给 Connection。
|
||||
为 Host 与 Client 两侧的 Cordis 环境提供 Typert RPC endpoint。Host 入口提供 `ctx.typertGateway`,`@deepseek-ai/dsh-api-gateway/client` 则提供 `ctx.remote`;两者使用同一份生成的 `InvocationDescriptor` 约定,并将业务选择交给 API Remotes,将传输、请求关联、信任和响应封装交给 Connection。
|
||||
|
||||
## Host 服务:`TypertGatewayService`(ctx key:`typertGateway`)
|
||||
|
||||
每次调用时,`ctx.typertGateway.invoke()` 都会解析当前的描述符和 Cordis 服务,校验具名参数是否完全匹配,解析已注册的对象或 Context 身份标识,调用公开的业务方法,并校验其结果。业务服务继承 [`dsh-type-meta`](../../typert/type-meta/README.md) 的 `GatewayService`,并用 `@Remote` 或 `@RemoteScope` 标记方法;已有其他基类时仍可改用 `bindTypeRTGateway()`。
|
||||
每次调用时,`ctx.typertGateway.invoke()` 都会解析当前的描述符和 Cordis 服务,校验具名参数是否完全匹配,解析已注册的对象或 Context 身份标识,调用公开的业务方法,并校验其结果。业务服务继承 [`dsh-typert-protocol`](../../typert/protocol/README.md) 的 `TypertRemoteService`,并用 `@Remote` 或 `@RemoteScope` 标记方法;已有其他基类时仍可改用 `bindTypertRemote()`。
|
||||
|
||||
严格模式从 `ctx.typert.local` 读取生成的调用描述符。查找参数使用 `ctx.typert.lookups` 中当前有效的 resolver:业务包注册稳定声明与默认策略,Host 组合可用 effect-scoped `configure()` 覆盖解析行为;`@RemoteScope` 则通过已注册的 Host Context 提供方解析其接收者。SRC 模式是开发阶段的回退路径,适用于从未具备严格定义的端点;它解析简单参数名,并且只允许非查找参数使用可安全表示为 JSON 的值。已观测到的严格定义一旦撤回,系统会直接报错,而不会降低校验强度。
|
||||
|
||||
Connection 可用时,Host 入口会在 Connection 共享的 `/api` FetchHandler 上注册 trusted-host interceptor。Connection 把这个复合 handler 交给 HTTP bridge;handler 将已认领 endpoint 分发给 Gateway,未认领 endpoint 则交给 API Proxy。直接调用 `invoke()` 会保留业务错误;`TypertGatewayError` 可区分分发、绑定、提供方、查找、Context、参数和编解码器各自负责的故障。resolver 可以用 `TypeRTLookupFailure` 携带既有 RPC error,使冷恢复失败或 ownership fence 等策略拒绝保持原错误码。
|
||||
Connection 可用时,Host 入口会在 Connection 共享的 `/api` FetchHandler 上注册 trusted-host interceptor。Connection 把这个复合 handler 交给 HTTP bridge;handler 将已认领 endpoint 分发给 Gateway,未认领 endpoint 则交给 API Proxy。直接调用 `invoke()` 会保留业务错误;`TypertGatewayError` 可区分分发、绑定、提供方、查找、Context、参数和编解码器各自负责的故障。resolver 可以用 `TypertLookupFailure` 携带既有 RPC error,使冷恢复失败或 ownership fence 等策略拒绝保持原错误码。
|
||||
|
||||
支持取消的 Remote 方法会把 `signal: AbortSignal` 声明为最后一个 Host 参数。signal 是 descriptor 元数据,而不是 wire 参数:Connection 将它提供给 Gateway,Gateway 则在已解码的业务参数之后注入它。SRC 识别这个保留的末位参数名,严格生成还要求它具有全局 `AbortSignal` 类型。
|
||||
|
||||
@@ -22,7 +22,7 @@ Connection 可用时,Host 入口会在 Connection 共享的 `/api` FetchHandle
|
||||
|
||||
`ctx.remote.$on()` 订阅一条被转发的 Host 事件。它的合法键恰好等于 Host 装配声明的转发选择,listener 类型就是事件所属包自己的 Cordis `Events` 声明,因此不存在会与之漂移的第二份签名。每个订阅归属发起调用的 fiber,并随该 fiber 一起消失。投递是单向的,并按注册顺序进行;抛错的 listener 会被记录并与其余 listener 隔离,绝不影响帧泵。`ctx.remote.$dispatch()` 是该面的另一半,且属于载体:持有 Host 帧 sink 的 Client 半把每个解码后的帧交进来,收到无人订阅的事件名即丢弃,因为 wire 上出现什么取决于 Host 的转发选择。消费方只订阅,绝不调用它。
|
||||
|
||||
生成的声明合并通过共享的 `TypeRTClientRemote` 约定提供 TypeScript API。Client 入口不包含 Host 服务或 Host Cordis 接口合并;方法查找和调用使用普通对象与函数,而不使用 JavaScript Proxy。
|
||||
生成的声明合并通过共享的 `TypertClientRemote` 约定提供 TypeScript API。Client 入口不包含 Host 服务或 Host Cordis 接口合并;方法查找和调用使用普通对象与函数,而不使用 JavaScript Proxy。
|
||||
|
||||
## 模型体验
|
||||
|
||||
@@ -34,7 +34,7 @@ Connection 可用时,Host 入口会在 Connection 共享的 `/api` FetchHandle
|
||||
|
||||
## 已知限制与延期工作
|
||||
|
||||
- Connection 适配器将普通分发故障和业务异常映射为 RPC 的 `internal` 代码,且不附带详细信息;`TypeRTLookupFailure` 携带的 lookup 策略错误会原样返回。结构化的 `TypertGatewayError` 类别仅供同进程调用方使用。
|
||||
- Connection 适配器将普通分发故障和业务异常映射为 RPC 的 `internal` 代码,且不附带详细信息;`TypertLookupFailure` 携带的 lookup 策略错误会原样返回。结构化的 `TypertGatewayError` 类别仅供同进程调用方使用。
|
||||
- SRC 模式仅支持名称唯一的标识符参数,不支持解构、默认值或剩余参数。它只校验值能否安全表示为 JSON,不校验生成的业务类型,也绝不会推断可选字段。
|
||||
- Client 侧只能挂载严格模式生成的贡献项。SRC 标记不具备 Client 编解码器或类型投影。
|
||||
- 该包只分发一元方法。增量会话数据通过同一个 Connection 上独立的具名流协议传输。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@deepseek-ai/dsh-api-gateway",
|
||||
"description": "TypeRT Remote Host dispatcher and Client API endpoint",
|
||||
"description": "Typert Remote Host dispatcher and Client API endpoint",
|
||||
"version": "0.0.1-rc.2",
|
||||
"publishConfig": {
|
||||
"access": "restricted"
|
||||
@@ -56,7 +56,7 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@deepseek-ai/dsh-type-meta": "workspace:^"
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/dsh-client-connection": "workspace:^",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Client projection of generated TypeRT Remote descriptors. Contributions
|
||||
* Client projection of generated Typert Remote descriptors. Contributions
|
||||
* install traced `remote.<namespace>` services; no JavaScript Proxy
|
||||
* participates in method lookup, invocation, or type exposure.
|
||||
*/
|
||||
@@ -9,13 +9,13 @@ import type { Context, Events } from '@deepseek-ai/cordis'
|
||||
import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import type {
|
||||
InvocationDescriptor,
|
||||
TypeRTClientRemote,
|
||||
TypertClientRemote,
|
||||
RemoteResult,
|
||||
TypeRTCodec,
|
||||
TypeRTDisposer,
|
||||
TypeRTRemoteContribution,
|
||||
TypeRTRemoteEvent,
|
||||
} from '@deepseek-ai/dsh-type-meta'
|
||||
TypertCodec,
|
||||
TypertDisposer,
|
||||
TypertRemoteContribution,
|
||||
TypertRemoteEvent,
|
||||
} from '@deepseek-ai/dsh-typert-protocol'
|
||||
|
||||
interface MountToken {
|
||||
active: boolean
|
||||
@@ -25,7 +25,7 @@ interface MountToken {
|
||||
interface ScopedProjection {
|
||||
readonly context: string
|
||||
readonly wire: string
|
||||
readonly codec: TypeRTCodec
|
||||
readonly codec: TypertCodec
|
||||
readonly parameterIndex?: number
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ interface BoundContextIdentity {
|
||||
|
||||
interface RemoteNamespaceHandle {
|
||||
readonly service: RemoteNamespaceService
|
||||
readonly dispose: TypeRTDisposer
|
||||
readonly dispose: TypertDisposer
|
||||
}
|
||||
|
||||
/** Typed Remote service augmented by generated direct namespaces. */
|
||||
export type ClientRemote = TypeRTClientRemote
|
||||
export type ClientRemote = TypertClientRemote
|
||||
|
||||
declare module '@deepseek-ai/cordis' {
|
||||
interface Context {
|
||||
@@ -62,7 +62,7 @@ declare module '@deepseek-ai/cordis' {
|
||||
}
|
||||
}
|
||||
|
||||
/** Required Client services: the TypeRT registry and the existing Connection carrier. */
|
||||
/** Required Client services: the Typert registry and the existing Connection carrier. */
|
||||
export const inject = ['typert', 'connection']
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ interface RemoteEventSubscription {
|
||||
readonly listener: RemoteEventListener
|
||||
}
|
||||
|
||||
class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
class ClientRemoteService extends Service implements TypertClientRemote {
|
||||
private readonly ownerCtx: Context
|
||||
private readonly namespaces = new Map<string, RemoteNamespaceHandle>()
|
||||
private readonly subscriptions = new Map<string, RemoteEventSubscription[]>()
|
||||
@@ -97,7 +97,7 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
ctx.effect(() => () => { this.subscriptions.clear() }, 'api-gateway.client.subscriptions')
|
||||
}
|
||||
|
||||
async $mount(contribution: TypeRTRemoteContribution): ReturnType<TypeRTClientRemote['$mount']> {
|
||||
async $mount(contribution: TypertRemoteContribution): ReturnType<TypertClientRemote['$mount']> {
|
||||
const callerCtx = this.ctx
|
||||
const owned = callerCtx.effect(async () => {
|
||||
const dispose = await this.enqueue(() => this.mountContribution(callerCtx, contribution))
|
||||
@@ -107,10 +107,10 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
return async () => { await owned() }
|
||||
}
|
||||
|
||||
$on<Event extends TypeRTRemoteEvent>(
|
||||
$on<Event extends TypertRemoteEvent>(
|
||||
event: Event,
|
||||
listener: Events[Event],
|
||||
): ReturnType<TypeRTClientRemote['$on']> {
|
||||
): ReturnType<TypertClientRemote['$on']> {
|
||||
// The table is keyed by the runtime event name, so the argument list this
|
||||
// signature pins per event cannot survive in it; `$deliver` restores it
|
||||
// from the frame the Host emitted for that same name.
|
||||
@@ -130,7 +130,7 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
/**
|
||||
* Deliver one forwarded event in registration order, isolating a listener
|
||||
* that fails either synchronously or by rejecting a returned promise; see
|
||||
* {@link TypeRTClientRemote.$dispatch} for the caller contract.
|
||||
* {@link TypertClientRemote.$dispatch} for the caller contract.
|
||||
*/
|
||||
$dispatch(event: string, args: readonly unknown[]): void {
|
||||
const listeners = this.subscriptions.get(event)
|
||||
@@ -173,11 +173,11 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
|
||||
private async mountContribution(
|
||||
callerCtx: Context,
|
||||
contribution: TypeRTRemoteContribution,
|
||||
): Promise<TypeRTDisposer> {
|
||||
contribution: TypertRemoteContribution,
|
||||
): Promise<TypertDisposer> {
|
||||
this.validateContribution(contribution)
|
||||
const disposeRemote = callerCtx.typert.remotes.register(contribution)
|
||||
const installed: TypeRTDisposer[] = []
|
||||
const installed: TypertDisposer[] = []
|
||||
try {
|
||||
for (const descriptor of contribution.descriptors) installed.push(await this.install(descriptor))
|
||||
} catch (error) {
|
||||
@@ -191,7 +191,7 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
}
|
||||
}
|
||||
|
||||
private validateContribution(contribution: TypeRTRemoteContribution): void {
|
||||
private validateContribution(contribution: TypertRemoteContribution): void {
|
||||
const direct = new Map<string, Set<string>>()
|
||||
const scoped = new Map<string, Set<string>>()
|
||||
const add = (
|
||||
@@ -235,9 +235,9 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
}
|
||||
}
|
||||
|
||||
private async install(descriptor: InvocationDescriptor): Promise<TypeRTDisposer> {
|
||||
private async install(descriptor: InvocationDescriptor): Promise<TypertDisposer> {
|
||||
const token: MountToken = { active: true, abort: new AbortController() }
|
||||
const installed: TypeRTDisposer[] = []
|
||||
const installed: TypertDisposer[] = []
|
||||
try {
|
||||
if (descriptor.invocation.kind === 'direct') {
|
||||
installed.push(await this.installDirect(descriptor, token))
|
||||
@@ -259,7 +259,7 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
}
|
||||
}
|
||||
|
||||
private async installDirect(descriptor: InvocationDescriptor, token: MountToken): Promise<TypeRTDisposer> {
|
||||
private async installDirect(descriptor: InvocationDescriptor, token: MountToken): Promise<TypertDisposer> {
|
||||
const namespace = await this.namespace(descriptor.namespace)
|
||||
try {
|
||||
namespace.service.installDirect(descriptor, token)
|
||||
@@ -277,7 +277,7 @@ class ClientRemoteService extends Service implements TypeRTClientRemote {
|
||||
descriptor: InvocationDescriptor,
|
||||
projection: ScopedProjection,
|
||||
token: MountToken,
|
||||
): Promise<TypeRTDisposer> {
|
||||
): Promise<TypertDisposer> {
|
||||
const namespace = await this.namespace(descriptor.namespace)
|
||||
try {
|
||||
namespace.service.installScoped(descriptor, projection, token)
|
||||
@@ -557,13 +557,13 @@ function requireStrictDescriptor(descriptor: InvocationDescriptor): void {
|
||||
}
|
||||
}
|
||||
|
||||
function requireStrictCodec(codec: TypeRTCodec, endpoint: string, field: string): void {
|
||||
function requireStrictCodec(codec: TypertCodec, endpoint: string, field: string): void {
|
||||
if (codec.mode !== 'strict') {
|
||||
throw new Error(`client api: generated Remote ${endpoint} field ${JSON.stringify(field)} has no strict codec`)
|
||||
}
|
||||
}
|
||||
|
||||
function parse(codec: TypeRTCodec, value: unknown, endpoint: string, field: string): unknown {
|
||||
function parse(codec: TypertCodec, value: unknown, endpoint: string, field: string): unknown {
|
||||
if (codec.mode !== 'strict') {
|
||||
throw new Error(`client api: generated Remote ${endpoint} field ${JSON.stringify(field)} has no strict codec`)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Live TypeRT Remote dispatch over Cordis Services and registered providers.
|
||||
* Live Typert Remote dispatch over Cordis Services and registered providers.
|
||||
* Transport, request correlation, and response envelopes belong to Connection.
|
||||
* @module @deepseek-ai/dsh-api-gateway
|
||||
*/
|
||||
@@ -8,12 +8,12 @@ import { Context, Service, symbols } from '@deepseek-ai/cordis'
|
||||
import type { ConnectionRpcHandler } from '@deepseek-ai/dsh-client-connection'
|
||||
import {
|
||||
remoteMethods,
|
||||
TypeRTLookupFailure,
|
||||
TypertLookupFailure,
|
||||
type InvocationDescriptor,
|
||||
type InvocationParameterDescriptor,
|
||||
type TypeRTCodec,
|
||||
type TypeRTGatewayBinding,
|
||||
} from '@deepseek-ai/dsh-type-meta'
|
||||
type TypertCodec,
|
||||
type TypertGatewayBinding,
|
||||
} from '@deepseek-ai/dsh-typert-protocol'
|
||||
import type {
|
||||
InvokeRemoteRequest,
|
||||
TypertGateway,
|
||||
@@ -32,7 +32,7 @@ interface GatewayErrorOptions {
|
||||
}
|
||||
|
||||
interface ResolvedBinding {
|
||||
readonly binding: TypeRTGatewayBinding
|
||||
readonly binding: TypertGatewayBinding
|
||||
readonly original: object
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class RemoteInvocationCancelled extends Error {
|
||||
|
||||
/**
|
||||
* Resolve strict generated definitions or conservative SRC markers against
|
||||
* current Cordis Services and TypeRT providers.
|
||||
* current Cordis Services and Typert providers.
|
||||
* @typert service typertGateway
|
||||
*/
|
||||
export class TypertGatewayService extends Service implements TypertGateway {
|
||||
@@ -93,8 +93,8 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
private srcClaims: ReadonlySet<string> | undefined
|
||||
|
||||
/**
|
||||
* Register the Gateway against the active TypeRT registry.
|
||||
* @param ctx - owning Host Context with TypeRT registry access.
|
||||
* Register the Gateway against the active Typert registry.
|
||||
* @param ctx - owning Host Context with Typert registry access.
|
||||
*/
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'typertGateway')
|
||||
@@ -126,7 +126,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
const receiver = this.ctx.get(serviceKey) as unknown
|
||||
if (!isObject(receiver)) continue
|
||||
const original = originalOf(receiver)
|
||||
const binding = Reflect.get(original, 'typertGateway') as unknown
|
||||
const binding = Reflect.get(original, 'typertRemote') as unknown
|
||||
if (!isObject(binding) || typeof Reflect.get(binding, 'namespace') !== 'string') continue
|
||||
const namespace = Reflect.get(binding, 'namespace') as string
|
||||
for (const candidate of remoteMethods(original)) {
|
||||
@@ -241,7 +241,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
const receiver = this.ctx.get(serviceKey) as unknown
|
||||
if (!isObject(receiver)) continue
|
||||
const original = originalOf(receiver)
|
||||
const value = Reflect.get(original, 'typertGateway') as unknown
|
||||
const value = Reflect.get(original, 'typertRemote') as unknown
|
||||
if (value === undefined) continue
|
||||
const binding = readBinding(value, original, serviceKey, endpoint)
|
||||
if (binding.namespace !== namespace) continue
|
||||
@@ -263,7 +263,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
}
|
||||
|
||||
private srcDescriptor(
|
||||
binding: TypeRTGatewayBinding,
|
||||
binding: TypertGatewayBinding,
|
||||
marker: ReturnType<typeof remoteMethods>[number],
|
||||
method: string,
|
||||
endpoint: string,
|
||||
@@ -385,7 +385,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
try {
|
||||
context = await provider.resolve(identity)
|
||||
} catch (cause) {
|
||||
if (cause instanceof TypeRTLookupFailure) throw cause
|
||||
if (cause instanceof TypertLookupFailure) throw cause
|
||||
throw new TypertGatewayError(
|
||||
'context-failed',
|
||||
endpoint,
|
||||
@@ -448,7 +448,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
|
||||
try {
|
||||
resolved = await provider.resolve(value)
|
||||
} catch (cause) {
|
||||
if (cause instanceof TypeRTLookupFailure) throw cause
|
||||
if (cause instanceof TypertLookupFailure) throw cause
|
||||
throw new TypertGatewayError(
|
||||
'lookup-failed',
|
||||
endpoint,
|
||||
@@ -475,7 +475,7 @@ function rpcFailure(error: unknown): ConnectionRpcResult {
|
||||
error: { code: 'cancelled', message: error.message, details: {} },
|
||||
}
|
||||
}
|
||||
if (error instanceof TypeRTLookupFailure) {
|
||||
if (error instanceof TypertLookupFailure) {
|
||||
return { ok: false, error: error.failure as ConnectionRpcError }
|
||||
}
|
||||
return {
|
||||
@@ -499,12 +499,12 @@ function validateBinding(
|
||||
endpoint: string,
|
||||
): ResolvedBinding {
|
||||
const original = originalOf(receiver)
|
||||
const value = Reflect.get(original, 'typertGateway') as unknown
|
||||
const value = Reflect.get(original, 'typertRemote') as unknown
|
||||
if (value === undefined) {
|
||||
throw new TypertGatewayError(
|
||||
'binding-invalid',
|
||||
endpoint,
|
||||
`Service ${JSON.stringify(serviceKey)} has no visible typertGateway binding`,
|
||||
`Service ${JSON.stringify(serviceKey)} has no visible typertRemote binding`,
|
||||
)
|
||||
}
|
||||
return {
|
||||
@@ -519,7 +519,7 @@ function readBinding(
|
||||
serviceKey: string,
|
||||
endpoint: string,
|
||||
namespace?: string,
|
||||
): TypeRTGatewayBinding {
|
||||
): TypertGatewayBinding {
|
||||
if (!isObject(value)
|
||||
|| Reflect.get(value, 'service') !== original
|
||||
|| Reflect.get(value, 'serviceKey') !== serviceKey
|
||||
@@ -528,10 +528,10 @@ function readBinding(
|
||||
throw new TypertGatewayError(
|
||||
'binding-invalid',
|
||||
endpoint,
|
||||
`Service ${JSON.stringify(serviceKey)} has an inconsistent typertGateway binding`,
|
||||
`Service ${JSON.stringify(serviceKey)} has an inconsistent typertRemote binding`,
|
||||
)
|
||||
}
|
||||
return value as unknown as TypeRTGatewayBinding
|
||||
return value as unknown as TypertGatewayBinding
|
||||
}
|
||||
|
||||
function originalOf(receiver: object): object {
|
||||
@@ -612,7 +612,7 @@ function assertExactArguments(
|
||||
}
|
||||
|
||||
function decode(
|
||||
codec: TypeRTCodec,
|
||||
codec: TypertCodec,
|
||||
value: unknown,
|
||||
code: 'input-invalid' | 'result-invalid',
|
||||
endpoint: string,
|
||||
|
||||
@@ -15,7 +15,7 @@ export const name = 'api-gateway-invariant'
|
||||
export const inject = ['invariants']
|
||||
|
||||
/**
|
||||
* No runtime invariant: Host calls re-read authoritative Cordis and TypeRT
|
||||
* No runtime invariant: Host calls re-read authoritative Cordis and Typert
|
||||
* state, while Client methods, descriptors, and `$on` subscriptions mutate in
|
||||
* one owned effect.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Carrier-independent TypeRT Gateway request, service, and error contracts.
|
||||
* Carrier-independent Typert Gateway request, service, and error contracts.
|
||||
* @module @deepseek-ai/dsh-api-gateway/types
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,7 @@ export interface TypertGateway {
|
||||
|
||||
declare module '@deepseek-ai/cordis' {
|
||||
interface Context {
|
||||
/** Host dispatcher for TypeRT Remote calls. */
|
||||
/** Host dispatcher for Typert Remote calls. */
|
||||
typertGateway: TypertGateway
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client
|
||||
import type {
|
||||
InvocationDescriptor,
|
||||
RemoteResult,
|
||||
TypeRTClientRemote,
|
||||
TypeRTContext,
|
||||
TypeRTRemoteScopeApi,
|
||||
TypeRTRemoteNamespace,
|
||||
} from '@deepseek-ai/dsh-type-meta'
|
||||
TypertClientRemote,
|
||||
TypertContext,
|
||||
TypertRemoteScopeApi,
|
||||
TypertRemoteNamespace,
|
||||
} from '@deepseek-ai/dsh-typert-protocol'
|
||||
import TypertRegistry from '@deepseek-ai/dsh-typert-registry'
|
||||
import type { ClientRemote } from '../src/client/index.ts'
|
||||
import { apply, inject } from '../src/client/index.ts'
|
||||
@@ -35,14 +35,14 @@ declare module '@deepseek-ai/cordis' {
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@deepseek-ai/dsh-type-meta' {
|
||||
interface TypeRTRemoteEventSelection extends Record<'fixture/changed' | 'fixture/idle', true> {}
|
||||
declare module '@deepseek-ai/dsh-typert-protocol' {
|
||||
interface TypertRemoteEventSelection extends Record<'fixture/changed' | 'fixture/idle', true> {}
|
||||
|
||||
interface TypeRTContextMap {
|
||||
fixture: TypeRTContext<string>
|
||||
interface TypertContextMap {
|
||||
fixture: TypertContext<string>
|
||||
}
|
||||
|
||||
interface TypeRTRemoteMap {
|
||||
interface TypertRemoteMap {
|
||||
'probe/create': (
|
||||
agentId: string,
|
||||
request: { readonly objective: string },
|
||||
@@ -51,7 +51,7 @@ declare module '@deepseek-ai/dsh-type-meta' {
|
||||
'probe/maybe': (value: string | null | undefined) => Promise<RemoteResult<string | null | undefined>>
|
||||
}
|
||||
|
||||
interface TypeRTRemoteScopeMap {
|
||||
interface TypertRemoteScopeMap {
|
||||
'fixture:probe/create': (
|
||||
request: { readonly objective: string },
|
||||
signal?: AbortSignal,
|
||||
@@ -61,14 +61,14 @@ declare module '@deepseek-ai/dsh-type-meta' {
|
||||
) => Promise<RemoteResult<{ readonly renamed: boolean }>>
|
||||
}
|
||||
|
||||
interface TypeRTRemoteNamespaceMap {
|
||||
probe: TypeRTRemoteNamespace<'probe'>
|
||||
interface TypertRemoteNamespaceMap {
|
||||
probe: TypertRemoteNamespace<'probe'>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type FixtureContext = Omit<Context, 'remote'> & {
|
||||
readonly remote: TypeRTClientRemote & TypeRTRemoteScopeApi<'fixture'>
|
||||
readonly remote: TypertClientRemote & TypertRemoteScopeApi<'fixture'>
|
||||
}
|
||||
|
||||
// Compile-time contract of `$on`: the key face is the forwarding selection and
|
||||
@@ -171,7 +171,7 @@ async function benchFiber(
|
||||
return { ctx, client }
|
||||
}
|
||||
|
||||
describe('Client TypeRT API', () => {
|
||||
describe('Client Typert API', () => {
|
||||
it('mounts concrete direct methods, validates both boundaries, and withdraws retained handles', async () => {
|
||||
const call = vi.fn<ConnectionHandle['rpc']['call']>()
|
||||
.mockResolvedValue({ ok: true, value: { ref: 'goal-1' } })
|
||||
|
||||
@@ -4,17 +4,17 @@ import { describe, expect, it } from 'vitest'
|
||||
import { Context, Service, symbols } from '@deepseek-ai/cordis'
|
||||
import { z } from 'zod'
|
||||
import { apply as applyConnection, inject as connectionInject } from '@deepseek-ai/dsh-client-connection'
|
||||
import type { HttpServerService, WebRoute } from '@deepseek-ai/dsh-host-webserver'
|
||||
import type { WebServer, WebRoute } from '@deepseek-ai/dsh-host-webserver'
|
||||
import {
|
||||
bindTypeRTGateway,
|
||||
bindTypertRemote,
|
||||
Remote,
|
||||
RemoteScope,
|
||||
TypeRTLookupFailure,
|
||||
TypertLookupFailure,
|
||||
type InvocationDescriptor,
|
||||
type TypeRTContext,
|
||||
type TypeRTLookup,
|
||||
type TypeRTLookupProvider,
|
||||
} from '@deepseek-ai/dsh-type-meta'
|
||||
type TypertContext,
|
||||
type TypertLookup,
|
||||
type TypertLookupProvider,
|
||||
} from '@deepseek-ai/dsh-typert-protocol'
|
||||
import TypertRegistry, { type TypertContribution } from '@deepseek-ai/dsh-typert-registry'
|
||||
import TypertGatewayService, { TypertGatewayError } from '@deepseek-ai/dsh-api-gateway'
|
||||
|
||||
@@ -26,14 +26,14 @@ interface MarkedContext extends Context {
|
||||
readonly fixtureScope?: string
|
||||
}
|
||||
|
||||
declare module '@deepseek-ai/dsh-type-meta' {
|
||||
interface TypeRTLookupMap {
|
||||
gatewayFixture: TypeRTLookup<FixtureAgent, string>
|
||||
gatewayFixtureAlias: TypeRTLookup<FixtureAgent, string>
|
||||
declare module '@deepseek-ai/dsh-typert-protocol' {
|
||||
interface TypertLookupMap {
|
||||
gatewayFixture: TypertLookup<FixtureAgent, string>
|
||||
gatewayFixtureAlias: TypertLookup<FixtureAgent, string>
|
||||
}
|
||||
|
||||
interface TypeRTContextMap {
|
||||
gatewayFixture: TypeRTContext<string>
|
||||
interface TypertContextMap {
|
||||
gatewayFixture: TypertContext<string>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ const emptyModel: TypertContribution['model'] = {
|
||||
}
|
||||
|
||||
class GoalService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'goals')
|
||||
readonly typertRemote = bindTypertRemote(this, 'goals')
|
||||
readonly calls: string[] = []
|
||||
lastSignal: AbortSignal | undefined
|
||||
nextResult: unknown = undefined
|
||||
@@ -137,7 +137,7 @@ class FakeConnectionService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
function fakeHttpServer(routes: WebRoute[]): Pick<HttpServerService, 'register' | 'tapIndex' | 'port'> {
|
||||
function fakeHttpServer(routes: WebRoute[]): Pick<WebServer, 'register' | 'tapIndex' | 'port'> {
|
||||
return {
|
||||
register(route) {
|
||||
if (routes.some(candidate => candidate.kind === route.kind && candidate.path === route.path)) {
|
||||
@@ -169,7 +169,7 @@ async function serveRoute(route: WebRoute): Promise<{ readonly origin: string; c
|
||||
}
|
||||
|
||||
class FirstSharedService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'firstShared', { namespace: 'shared' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'firstShared', { namespace: 'shared' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'firstShared')
|
||||
@@ -182,7 +182,7 @@ class FirstSharedService extends Service {
|
||||
}
|
||||
|
||||
class SecondSharedService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'secondShared', { namespace: 'shared' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'secondShared', { namespace: 'shared' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'secondShared')
|
||||
@@ -195,7 +195,7 @@ class SecondSharedService extends Service {
|
||||
}
|
||||
|
||||
class DefaultParameterService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'defaultParameter', { namespace: 'invalid-default' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'defaultParameter', { namespace: 'invalid-default' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'defaultParameter')
|
||||
@@ -208,7 +208,7 @@ class DefaultParameterService extends Service {
|
||||
}
|
||||
|
||||
class DestructuredParameterService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'destructuredParameter', { namespace: 'invalid-destructure' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'destructuredParameter', { namespace: 'invalid-destructure' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'destructuredParameter')
|
||||
@@ -221,7 +221,7 @@ class DestructuredParameterService extends Service {
|
||||
}
|
||||
|
||||
class RestParameterService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'restParameter', { namespace: 'invalid-rest' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'restParameter', { namespace: 'invalid-rest' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'restParameter')
|
||||
@@ -234,7 +234,7 @@ class RestParameterService extends Service {
|
||||
}
|
||||
|
||||
class NonFinalSignalService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'nonFinalSignal', { namespace: 'invalid-signal' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'nonFinalSignal', { namespace: 'invalid-signal' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'nonFinalSignal')
|
||||
@@ -247,7 +247,7 @@ class NonFinalSignalService extends Service {
|
||||
}
|
||||
|
||||
class WrongBindingService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'notWrongBinding', { namespace: 'wrong-binding' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'notWrongBinding', { namespace: 'wrong-binding' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'wrongBinding')
|
||||
@@ -260,7 +260,7 @@ class WrongBindingService extends Service {
|
||||
}
|
||||
|
||||
class ExportedMethodService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'exportedMethod', { namespace: 'exported' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'exportedMethod', { namespace: 'exported' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'exportedMethod')
|
||||
@@ -273,7 +273,7 @@ class ExportedMethodService extends Service {
|
||||
}
|
||||
|
||||
class EmptyMethodService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'emptyMethod', { namespace: 'empty' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'emptyMethod', { namespace: 'empty' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'emptyMethod')
|
||||
@@ -286,7 +286,7 @@ class EmptyMethodService extends Service {
|
||||
}
|
||||
|
||||
class CollidingWireService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'collidingWire', { namespace: 'colliding-wire' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'collidingWire', { namespace: 'colliding-wire' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'collidingWire')
|
||||
@@ -299,7 +299,7 @@ class CollidingWireService extends Service {
|
||||
}
|
||||
|
||||
class ContextWireService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'contextWire', { namespace: 'context-wire' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'contextWire', { namespace: 'context-wire' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'contextWire')
|
||||
@@ -322,14 +322,14 @@ class NoBindingService extends Service {
|
||||
}
|
||||
|
||||
class ObservedClaimService extends Service {
|
||||
private readonly binding = bindTypeRTGateway(this, 'observedClaim', { namespace: 'observed-claim' })
|
||||
private readonly binding = bindTypertRemote(this, 'observedClaim', { namespace: 'observed-claim' })
|
||||
bindingReads = 0
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'observedClaim')
|
||||
}
|
||||
|
||||
get typertGateway() {
|
||||
get typertRemote() {
|
||||
this.bindingReads += 1
|
||||
return this.binding
|
||||
}
|
||||
@@ -341,7 +341,7 @@ class ObservedClaimService extends Service {
|
||||
}
|
||||
|
||||
class MissingMethodService extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'missingMethod', { namespace: 'missing-method' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'missingMethod', { namespace: 'missing-method' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'missingMethod')
|
||||
@@ -354,7 +354,7 @@ class MissingMethodService extends Service {
|
||||
}
|
||||
|
||||
class InheritedMethodBase extends Service {
|
||||
readonly typertGateway = bindTypeRTGateway(this, 'inheritedMethod', { namespace: 'inherited' })
|
||||
readonly typertRemote = bindTypertRemote(this, 'inheritedMethod', { namespace: 'inherited' })
|
||||
|
||||
constructor(ctx: Context) {
|
||||
super(ctx, 'inheritedMethod')
|
||||
@@ -546,7 +546,7 @@ describe('TypertGatewayService', () => {
|
||||
|
||||
it('preserves a Host Context policy rejection for the active RPC adapter', async () => {
|
||||
const { ctx } = await setup()
|
||||
const rejection = new TypeRTLookupFailure({ code: 'agent-busy', message: 'owned', details: { reason: 'subagent' } })
|
||||
const rejection = new TypertLookupFailure({ code: 'agent-busy', message: 'owned', details: { reason: 'subagent' } })
|
||||
ctx.typert.contexts.registerHost('gatewayFixture', {
|
||||
...contextProvider(ctx.extend()),
|
||||
resolve: async () => { throw rejection },
|
||||
@@ -892,10 +892,10 @@ describe('TypertGatewayService', () => {
|
||||
}), 'binding-invalid')
|
||||
|
||||
const plain: {
|
||||
typertGateway?: ReturnType<typeof bindTypeRTGateway>
|
||||
typertRemote?: ReturnType<typeof bindTypertRemote>
|
||||
run(value: string): string
|
||||
} = { run: value => value }
|
||||
plain.typertGateway = bindTypeRTGateway(plain, 'plainRemote', { namespace: 'plain' })
|
||||
plain.typertRemote = bindTypertRemote(plain, 'plainRemote', { namespace: 'plain' })
|
||||
ctx.provide('plainRemote', plain)
|
||||
ctx.typert.register({
|
||||
package: '@fixture/plain',
|
||||
@@ -1060,7 +1060,7 @@ describe('TypertGatewayService', () => {
|
||||
}
|
||||
ctx.typert.lookups.register('gatewayFixture', {
|
||||
...agentLookup({ id: 'agent-1' }),
|
||||
resolve: () => { throw new TypeRTLookupFailure(failure) },
|
||||
resolve: () => { throw new TypertLookupFailure(failure) },
|
||||
})
|
||||
const handler = rawConnection(ctx).handler
|
||||
if (handler === undefined) throw new Error('fixture Connection did not retain the /api interceptor')
|
||||
@@ -1103,7 +1103,7 @@ describe('TypertGatewayService', () => {
|
||||
it('dispatches claimed invocations through /api and leaves unclaimed endpoints to its fallback', async () => {
|
||||
const ctx = new Context().extend({ fixtureScope: 'http-caller' })
|
||||
const routes: WebRoute[] = []
|
||||
ctx.provide('httpServer', fakeHttpServer(routes) as HttpServerService)
|
||||
ctx.provide('webServer', fakeHttpServer(routes) as WebServer)
|
||||
const connectionFiber = ctx.plugin({ inject: [...connectionInject], apply: applyConnection })
|
||||
await connectionFiber
|
||||
await ctx.plugin(TypertRegistry)
|
||||
@@ -1242,7 +1242,7 @@ function registerAgentLookup(ctx: Context, agent: FixtureAgent): () => Promise<v
|
||||
return ctx.typert.lookups.register('gatewayFixture', agentLookup(agent))
|
||||
}
|
||||
|
||||
function agentLookup(agent: FixtureAgent): TypeRTLookupProvider<FixtureAgent, string> {
|
||||
function agentLookup(agent: FixtureAgent): TypertLookupProvider<FixtureAgent, string> {
|
||||
return {
|
||||
parameter: 'agent',
|
||||
wire: 'agentId',
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"path": "../../client/connection/tsconfig.client.json"
|
||||
},
|
||||
{
|
||||
"path": "../../typert/type-meta"
|
||||
"path": "../../typert/protocol"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
"path": "../../../vendor/cordis"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
},
|
||||
{
|
||||
"path": "../../client/connection/tsconfig.host.json"
|
||||
},
|
||||
{
|
||||
"path": "../../typert/type-meta"
|
||||
"path": "../../typert/protocol"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/api/remotes/README.md
|
||||
README.md: 288c63c9f43654dfec428a6a8955dc537efe81a6
|
||||
README.zh.md: 1fd599b08ecc1b4ae1dba738ce8946aa4eab5946
|
||||
README.md: 18d39c6e86f114d2aac2f24e5d15c13335eab020
|
||||
README.zh.md: bf3dfbbaa6e0c7bd1da8398977837d4cb19d4688
|
||||
|
||||
@@ -4,9 +4,9 @@ English | [中文](README.zh.md)
|
||||
|
||||
Two-sided BFF for Host Remote capabilities selected by this application. The Host entry owns Agent/Session identity policy; the Client entry imports generated `/remote` artifacts as runtime values, mounts each contribution through `ctx.remote.$mount()`, and re-exports their declaration merges. Client business packages depend on this facade rather than the Gateway implementation or individual Remote runtime entries.
|
||||
|
||||
`createApiRemoteAgentResolver()` reuses live Agents, resumes ordinary cold sessions, deduplicates concurrent resumes, preserves the subagent ownership fence, and configures the same resolver for TypeRT `agent` and `session` lookups. The standard Web API Proxy supplies its Agent defaults and scope setup, then uses the returned resolver for legacy methods, so migrated and unmigrated methods share one policy implementation.
|
||||
`createApiRemoteAgentResolver()` reuses live Agents, resumes ordinary cold sessions, deduplicates concurrent resumes, preserves the subagent ownership fence, and configures the same resolver for Typert `agent` and `session` lookups. The standard Web API Proxy supplies its Agent defaults and scope setup, then uses the returned resolver for legacy methods, so migrated and unmigrated methods share one policy implementation.
|
||||
|
||||
The current Client assembly mounts the Goal Remote contribution and the read-only Host plugin inventory contribution (`pluginInventory/list`). Cordis effect ownership withdraws every contribution when this assembly unloads, while `@deepseek-ai/dsh-api-gateway/client` owns descriptor validation, traced namespace Services, direct and scoped methods, invocation, and cancellation. The Client entry consumes the shared `TypeRTClientRemote` interface through Cordis and does not import the concrete Gateway. It re-exports the Gateway Client face's declaration merges type-only, so a consumer reaching the forwarded-event vocabulary through this facade gains no runtime edge to the Gateway implementation.
|
||||
The current Client assembly mounts the Goal Remote contribution and the read-only Host plugin inventory contribution (`pluginInventory/list`). Cordis effect ownership withdraws every contribution when this assembly unloads, while `@deepseek-ai/dsh-api-gateway/client` owns descriptor validation, traced namespace Services, direct and scoped methods, invocation, and cancellation. The Client entry consumes the shared `TypertClientRemote` interface through Cordis and does not import the concrete Gateway. It re-exports the Gateway Client face's declaration merges type-only, so a consumer reaching the forwarded-event vocabulary through this facade gains no runtime edge to the Gateway implementation.
|
||||
|
||||
This package contains no transport or Host service discovery logic. Its Client face can be reused by Web or a future TUI that provides the same React-free `ctx.remote` contract.
|
||||
|
||||
@@ -14,11 +14,11 @@ This package contains no transport or Host service discovery logic. Its Client f
|
||||
|
||||
`src/remote-events.ts` holds `API_REMOTE_FORWARDED_EVENTS`, the allowlist of Host cordis events this application forwards to consumers verbatim — no projection, no redaction, no renaming — and therefore the legal key set of `ctx.remote.$on`; the type-only `src/types.ts` derives its selection face. Forwarding one more event is an entry in that array and nothing else: the type projection, the consumer key face, and the Host forwarding loop all derive from it.
|
||||
|
||||
The listener signature is not restated here. Each allowlisted event's cordis `Events` declaration lives in its owner package's client-safe `./types` export (`dsh-agent-presets`, `dsh-commands`, `dsh-credentials`, `dsh-llm`, `dsh-settings`), and both faces of this package pull those declarations in, so "forwarded verbatim" holds by construction rather than by proof. The Host face additionally asserts the list against `TypeRTForwardableEvent`, which rejects a name that is not a declared event, one that binds an AgentScope, and one whose shape is not one-way.
|
||||
The listener signature is not restated here. Each allowlisted event's cordis `Events` declaration lives in its owner package's client-safe `./types` export (`dsh-agent-presets`, `dsh-commands`, `dsh-credentials`, `dsh-llm`, `dsh-settings`), and both faces of this package pull those declarations in, so "forwarded verbatim" holds by construction rather than by proof. The Host face additionally asserts the list against `TypertForwardableEvent`, which rejects a name that is not a declared event, one that binds an AgentScope, and one whose shape is not one-way.
|
||||
|
||||
## Build boundary
|
||||
|
||||
An ordinary repository package belongs to one TypeScript face: Host packages are registered in the root `tsconfig.host.json`, and Client packages in the root `tsconfig.client.json`. `api-remotes` is the only deliberate exception because its Host entry must participate in the Host TypeRT graph, while `src/client/index.ts` cannot compile until Host tsdown has generated the business packages' `/remote` declarations.
|
||||
An ordinary repository package belongs to one TypeScript face: Host packages are registered in the root `tsconfig.host.json`, and Client packages in the root `tsconfig.client.json`. `api-remotes` is the only deliberate exception because its Host entry must participate in the Host Typert graph, while `src/client/index.ts` cannot compile until Host tsdown has generated the business packages' `/remote` declarations.
|
||||
|
||||
This package's root `tsconfig.json` is only a solution that references `tsconfig.host.json` and `tsconfig.client.json`. The Host aggregate and direct Host consumers reference the former, while the Client aggregate and direct Client consumers reference the latter; the package-root solution must not enter either aggregate's dependency graph. The two projects own disjoint source files and `.tsbuildinfo` files but share the `lib/types` output directory, with one deliberate exception: `src/remote-events.ts` and `src/types.ts` are listed in BOTH faces' `files`, because the forwarded-event allowlist is the single control point over what a consumer can receive, and the Host forwarding loop and the Client `ctx.remote.$on` key face must read one declaration rather than two that could drift.
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
为本应用选定的 Host Remote 能力提供双侧 BFF。Host 入口负责 Agent/Session 身份策略;Client 入口以运行时值形式导入生成的 `/remote` 产物,通过 `ctx.remote.$mount()` 挂载每项贡献,并重新导出对应的声明合并。Client 业务包依赖该外观,而不依赖 Gateway 实现或单独的 Remote 运行时入口。
|
||||
|
||||
`createApiRemoteAgentResolver()` 会复用 live Agent、恢复普通冷会话、对并发恢复去重、保留 subagent ownership fence,并为 TypeRT `agent` 和 `session` lookup 配置同一个 resolver。标准 Web API Proxy 提供 Agent 默认值和 scope 设置,再将返回的 resolver 用于旧方法,使已迁移与未迁移方法共用同一份策略实现。
|
||||
`createApiRemoteAgentResolver()` 会复用 live Agent、恢复普通冷会话、对并发恢复去重、保留 subagent ownership fence,并为 Typert `agent` 和 `session` lookup 配置同一个 resolver。标准 Web API Proxy 提供 Agent 默认值和 scope 设置,再将返回的 resolver 用于旧方法,使已迁移与未迁移方法共用同一份策略实现。
|
||||
|
||||
当前 Client 组合挂载 Goal Remote 贡献和只读 Host 插件清单贡献(`pluginInventory/list`)。该组合卸载时,Cordis effect 的所有权机制会撤回所有贡献;`@deepseek-ai/dsh-api-gateway/client` 负责描述符校验、可追踪 namespace Service、直接与作用域方法、调用与取消。Client 入口通过 Cordis 消费共享的 `TypeRTClientRemote` 接口,不导入具体 Gateway;它只以 type-only 形式重新导出 Gateway Client face 的声明合并,因此消费端经由本外观取到转发事件词汇时,运行时不会多出一条通往 Gateway 实现的边。
|
||||
当前 Client 组合挂载 Goal Remote 贡献和只读 Host 插件清单贡献(`pluginInventory/list`)。该组合卸载时,Cordis effect 的所有权机制会撤回所有贡献;`@deepseek-ai/dsh-api-gateway/client` 负责描述符校验、可追踪 namespace Service、直接与作用域方法、调用与取消。Client 入口通过 Cordis 消费共享的 `TypertClientRemote` 接口,不导入具体 Gateway;它只以 type-only 形式重新导出 Gateway Client face 的声明合并,因此消费端经由本外观取到转发事件词汇时,运行时不会多出一条通往 Gateway 实现的边。
|
||||
|
||||
本包不包含传输逻辑或 Host 服务发现逻辑。Web 或未来的 TUI 只要提供同一份不依赖 React 的 `ctx.remote` 约定,均可复用其 Client face。
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
`src/remote-events.ts` 持有 `API_REMOTE_FORWARDED_EVENTS`——本应用原样转发给消费端的 Host cordis 事件名单(无投影、无脱敏、无改名),它同时就是 `ctx.remote.$on` 的合法键集;只含类型的 `src/types.ts` 派生其选择面。多转发一个事件只需在该数组里加一行:类型投影、消费端键面与 Host 转发循环全部由它派生。
|
||||
|
||||
监听器签名不在此处重写。名单内每条事件的 cordis `Events` 声明都住在其 owner 包 client-safe 的 `./types` 出口(`dsh-agent-presets`、`dsh-commands`、`dsh-credentials`、`dsh-llm`、`dsh-settings`),本包两个 face 都把那些声明纳入编译面,因此「原样转发」是构造性成立的,不需要另立证明。Host face 还额外把名单断言给 `TypeRTForwardableEvent`:未声明的事件名、绑定 AgentScope 的事件、以及形状不是单向的事件都会在此被拒绝。
|
||||
监听器签名不在此处重写。名单内每条事件的 cordis `Events` 声明都住在其 owner 包 client-safe 的 `./types` 出口(`dsh-agent-presets`、`dsh-commands`、`dsh-credentials`、`dsh-llm`、`dsh-settings`),本包两个 face 都把那些声明纳入编译面,因此「原样转发」是构造性成立的,不需要另立证明。Host face 还额外把名单断言给 `TypertForwardableEvent`:未声明的事件名、绑定 AgentScope 的事件、以及形状不是单向的事件都会在此被拒绝。
|
||||
|
||||
## 构建边界
|
||||
|
||||
仓库中的普通包只属于一个 TypeScript face:Host 包登记在根 `tsconfig.host.json`,Client 包登记在根 `tsconfig.client.json`。`api-remotes` 是唯一刻意拆分的特例,因为它的 Host 入口要参与 Host TypeRT 图,而 `src/client/index.ts` 必须等 Host tsdown 生成业务包的 `/remote` 声明后才能编译。
|
||||
仓库中的普通包只属于一个 TypeScript face:Host 包登记在根 `tsconfig.host.json`,Client 包登记在根 `tsconfig.client.json`。`api-remotes` 是唯一刻意拆分的特例,因为它的 Host 入口要参与 Host Typert 图,而 `src/client/index.ts` 必须等 Host tsdown 生成业务包的 `/remote` 声明后才能编译。
|
||||
|
||||
本包根 `tsconfig.json` 只是引用 `tsconfig.host.json` 与 `tsconfig.client.json` 的 solution。Host aggregate 和 Host 直接消费方引用前者,Client aggregate 和 Client 直接消费方引用后者;禁止把包根 solution 放进任一 aggregate 的依赖图。两个 project 拥有互不重叠的源码和 `.tsbuildinfo`,但共享 `lib/types` 输出目录——只有一处刻意的例外:`src/remote-events.ts` 与 `src/types.ts` **同时**列进两个 face 的 `files`,因为转发事件名单是「消费端能收到什么」的唯一控制点,Host 转发循环与 Client 的 `ctx.remote.$on` 键面必须读同一份声明,而不是两份可能彼此漂移的声明。
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"lib/types/**/*.d.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"@deepseek-ai/dsh-type-meta": "workspace:^"
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:^"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/cordis": "workspace:^",
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Context } from '@deepseek-ai/cordis'
|
||||
import type { Agent, AgentOptions, AgentSetup } from '@deepseek-ai/dsh-agent'
|
||||
import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type {} from '@deepseek-ai/dsh-session-persistence'
|
||||
import { TypeRTLookupFailure } from '@deepseek-ai/dsh-type-meta'
|
||||
import { TypertLookupFailure } from '@deepseek-ai/dsh-typert-protocol'
|
||||
import type {} from '@deepseek-ai/dsh-typert-registry'
|
||||
|
||||
/** Caller-facing failures preserved by the Gateway's RPC adapter. */
|
||||
@@ -111,12 +111,12 @@ export async function inspectApiRemoteSession(
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Host's shared Agent resolver and configure Agent/Session TypeRT lookups.
|
||||
* Create the Host's shared Agent resolver and configure Agent/Session Typert lookups.
|
||||
* Live Agents are reused, ordinary cold sessions resume once per identity, and
|
||||
* subagent-owned identities retain the legacy `agent-busy` fence.
|
||||
* @param ctx - owning Host Context.
|
||||
* @param options - defaults and Agent-scope setup used only for cold resume.
|
||||
* @returns resolver shared by legacy API Proxy methods and TypeRT lookups.
|
||||
* @returns resolver shared by legacy API Proxy methods and Typert lookups.
|
||||
*/
|
||||
export function createApiRemoteAgentResolver(
|
||||
ctx: Context,
|
||||
@@ -199,7 +199,7 @@ export function createApiRemoteAgentResolver(
|
||||
ctx.inject(['typert'], (typeCtx) => {
|
||||
const resolveAgent = async (sessionId: SessionId): Promise<Agent> => {
|
||||
const found = await agentFor(sessionId)
|
||||
if ('error' in found) throw new TypeRTLookupFailure(found.error)
|
||||
if ('error' in found) throw new TypertLookupFailure(found.error)
|
||||
return found.agent
|
||||
}
|
||||
typeCtx.typert.lookups.configure('agent', resolveAgent)
|
||||
|
||||
@@ -5,16 +5,16 @@ import commandsRemote from '@deepseek-ai/dsh-commands/remote'
|
||||
import goalsRemote from '@deepseek-ai/dsh-goal/remote'
|
||||
import pluginInventoryRemote from '@deepseek-ai/dsh-host-plugin-inventory/remote'
|
||||
import messageFeedbackRemote from '@deepseek-ai/dsh-message-feedback/remote'
|
||||
import type { TypeRTClientRemote } from '@deepseek-ai/dsh-type-meta'
|
||||
import type { TypertClientRemote } from '@deepseek-ai/dsh-typert-protocol'
|
||||
|
||||
export type { TypeRTClientRemote as ClientRemote } from '@deepseek-ai/dsh-type-meta'
|
||||
export type { TypertClientRemote as ClientRemote } from '@deepseek-ai/dsh-typert-protocol'
|
||||
export type { PluginInventorySnapshot } from '@deepseek-ai/dsh-host-plugin-inventory/types'
|
||||
export type {} from '@deepseek-ai/dsh-commands/remote'
|
||||
export type {} from '@deepseek-ai/dsh-goal/remote'
|
||||
export type {} from '@deepseek-ai/dsh-host-plugin-inventory/remote'
|
||||
export type {} from '@deepseek-ai/dsh-message-feedback/remote'
|
||||
// The forwarded-event allowlist's selection seat: without it in the consumer's
|
||||
// compilation face `TypeRTRemoteEvent` is `never` and every `$on` call fails.
|
||||
// compilation face `TypertRemoteEvent` is `never` and every `$on` call fails.
|
||||
export type { ApiRemoteForwardedEvent } from '../types.ts'
|
||||
// The owner packages' client-safe `./types` exports supply the `Events`
|
||||
// signatures `$on` hands to a listener, so a consumer reads the very
|
||||
@@ -37,14 +37,14 @@ export type {
|
||||
MuxFrame, PromptContentPart, QuestionResponsePayload, QueueAction, RpcError, RpcId, RpcReceipt,
|
||||
RpcRequest, RpcResponse, RpcResult, SessionId, SessionModels, SessionSearchItem,
|
||||
SessionSummary, SettingsNamespaceView, SettingsPathOpView, SkillEntry, StreamChunk,
|
||||
SubagentAddress, SubagentCatalog, TaskView, ToolCallView, ToolEventView, ToolResultView,
|
||||
SubagentAddress, SubagentCatalog, JobView, ToolCallView, ToolEventView, ToolResultView,
|
||||
WorkspaceId, WorkspaceView,
|
||||
} from '@deepseek-ai/dsh-client-connection/client'
|
||||
|
||||
declare module '@deepseek-ai/cordis' {
|
||||
interface Context {
|
||||
/** Generated Remote namespaces selected by this Client assembly. */
|
||||
remote: TypeRTClientRemote
|
||||
remote: TypertClientRemote
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** Host BFF entry and Loader shell for the Remote contribution assembly. */
|
||||
|
||||
import type { TypeRTForwardableEvent } from '@deepseek-ai/dsh-type-meta'
|
||||
import type { TypertForwardableEvent } from '@deepseek-ai/dsh-typert-protocol'
|
||||
import { API_REMOTE_FORWARDED_EVENTS } from './remote-events.ts'
|
||||
|
||||
// The owner packages' client-safe `./types` exports carry the cordis `Events`
|
||||
@@ -37,7 +37,7 @@ export type { ApiRemoteForwardedEvent } from './types.ts'
|
||||
// and every entry is ONE-WAY (a waterfall or bail shape returns something other
|
||||
// than void and is excluded). Widening the array to an event that fails any of
|
||||
// these fails here, not on the wire.
|
||||
API_REMOTE_FORWARDED_EVENTS satisfies readonly TypeRTForwardableEvent[]
|
||||
API_REMOTE_FORWARDED_EVENTS satisfies readonly TypertForwardableEvent[]
|
||||
|
||||
/** Host plugin body; the selected contributions mount only in Client environments. */
|
||||
export function apply(): void {}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const name = 'api-remotes-invariant'
|
||||
/** Service required before the companion can reserve package ownership. */
|
||||
export const inject = ['invariants']
|
||||
|
||||
/** No runtime invariant: TypeRT and the Agent/Session registries own the observed relationships. */
|
||||
/** No runtime invariant: Typert and the Agent/Session registries own the observed relationships. */
|
||||
const install: InvariantInstaller = () => {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,6 @@ import type { API_REMOTE_FORWARDED_EVENTS } from './remote-events.ts'
|
||||
/** Type projection of the allowlist; the consumer and the Host read this one. */
|
||||
export type ApiRemoteForwardedEvent = typeof API_REMOTE_FORWARDED_EVENTS[number]
|
||||
|
||||
declare module '@deepseek-ai/dsh-type-meta' {
|
||||
interface TypeRTRemoteEventSelection extends Record<ApiRemoteForwardedEvent, true> {}
|
||||
declare module '@deepseek-ai/dsh-typert-protocol' {
|
||||
interface TypertRemoteEventSelection extends Record<ApiRemoteForwardedEvent, true> {}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
import SessionStore from '@deepseek-ai/dsh-session'
|
||||
import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
|
||||
import { createApiRemoteAgentResolver } from '@deepseek-ai/dsh-api-remotes'
|
||||
import { TypeRTLookupFailure } from '@deepseek-ai/dsh-type-meta'
|
||||
import { TypertLookupFailure } from '@deepseek-ai/dsh-typert-protocol'
|
||||
import TypertRegistry from '@deepseek-ai/dsh-typert-registry'
|
||||
|
||||
const sid = (value: string): SessionId => value as SessionId
|
||||
@@ -147,7 +147,7 @@ describe('API Remote Agent resolver races', () => {
|
||||
if (provider === undefined) throw new Error('Agent Host Context provider was not mounted')
|
||||
|
||||
const resolution = provider.resolve(sessionId)
|
||||
await expect(resolution).rejects.toBeInstanceOf(TypeRTLookupFailure)
|
||||
await expect(resolution).rejects.toBeInstanceOf(TypertLookupFailure)
|
||||
await expect(resolution).rejects.toMatchObject({ failure: { code: 'agent-busy' } })
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
@@ -59,7 +59,7 @@ describe.skipIf(!requiredArtifacts)('Goal Remote built LIB chain', () => {
|
||||
|
||||
const routes = []
|
||||
const host = new Context()
|
||||
host.provide('httpServer', {
|
||||
host.provide('webServer', {
|
||||
register(route) {
|
||||
routes.push(route)
|
||||
return () => { routes.splice(routes.indexOf(route), 1) }
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"path": "../../settings/settings"
|
||||
},
|
||||
{
|
||||
"path": "../../typert/type-meta"
|
||||
"path": "../../typert/protocol"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
"path": "../../settings/settings"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
},
|
||||
{
|
||||
"path": "../../typert/registry"
|
||||
},
|
||||
{
|
||||
"path": "../../typert/type-meta"
|
||||
"path": "../../typert/protocol"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user