@mupt-ai/dari-gateway 0.0.0-stage → 0.2.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 +202 -0
- package/README.md +135 -2
- package/dari-gateway.example.yaml +28 -0
- package/package.json +42 -4
- package/src/bun.ts +4 -0
- package/src/context/eval_catalog.ts +11 -0
- package/src/context/interaction_fingerprint.ts +691 -0
- package/src/context/interaction_fingerprint_format.ts +189 -0
- package/src/context/interaction_lease_depth.ts +150 -0
- package/src/context/lease_history.ts +200 -0
- package/src/context/pricing.ts +30 -0
- package/src/context/provider_prompt_accounting.ts +241 -0
- package/src/context/routing_context.ts +337 -0
- package/src/http/auth.ts +43 -0
- package/src/http/errors.ts +114 -0
- package/src/http/handler.ts +110 -0
- package/src/http/http2_server.ts +122 -0
- package/src/http/serve.ts +119 -0
- package/src/index.ts +22 -0
- package/src/ingress/anthropic_messages.ts +162 -0
- package/src/ingress/anthropic_models.ts +28 -0
- package/src/ingress/chat_completions.ts +49 -0
- package/src/ingress/claude_code/request_context.ts +36 -0
- package/src/ingress/codex.ts +81 -0
- package/src/ingress/codex_models.ts +113 -0
- package/src/ingress/json.ts +113 -0
- package/src/ingress/models.ts +55 -0
- package/src/interaction/capabilities.ts +30 -0
- package/src/interaction/image.ts +12 -0
- package/src/interaction/portable_reasoning_state.ts +25 -0
- package/src/interaction/provider_continuation_state.ts +36 -0
- package/src/interaction/tool_identity.ts +65 -0
- package/src/interaction/types.ts +282 -0
- package/src/models/context_limits.ts +8 -0
- package/src/models/execution_provider.ts +22 -0
- package/src/models/gateways.ts +73 -0
- package/src/models/ids.ts +26 -0
- package/src/models/provider_defaults.ts +47 -0
- package/src/models/runtime_overrides.ts +221 -0
- package/src/observability/errors.ts +25 -0
- package/src/platform/platform.ts +204 -0
- package/src/platform/routing_contract.ts +6 -0
- package/src/protocol/input/anthropic_messages.ts +531 -0
- package/src/protocol/input/chat_completions.ts +255 -0
- package/src/protocol/input/chat_completions_validation.ts +293 -0
- package/src/protocol/input/openai_responses.ts +749 -0
- package/src/protocol/input/router_model.ts +53 -0
- package/src/protocol/output/anthropic_messages.ts +32 -0
- package/src/protocol/output/anthropic_messages_output.ts +129 -0
- package/src/protocol/output/anthropic_messages_stream.ts +281 -0
- package/src/protocol/output/chat_completions.ts +451 -0
- package/src/protocol/output/chat_reasoning_detail.ts +19 -0
- package/src/protocol/output/delivered_stream_snapshot.ts +31 -0
- package/src/protocol/output/openai_responses.ts +30 -0
- package/src/protocol/output/openai_responses_output.ts +159 -0
- package/src/protocol/output/openai_responses_stream.ts +631 -0
- package/src/protocol/output/sse_stream.ts +102 -0
- package/src/providers/anthropic_safeguards.ts +115 -0
- package/src/providers/aws_assume_role.ts +147 -0
- package/src/providers/cancel_estimate.ts +140 -0
- package/src/providers/execution.ts +800 -0
- package/src/providers/model_capabilities.ts +50 -0
- package/src/providers/pi.ts +499 -0
- package/src/providers/pi_context.ts +466 -0
- package/src/providers/pi_options.ts +416 -0
- package/src/providers/pi_output.ts +500 -0
- package/src/providers/provider_attempt_runner.ts +153 -0
- package/src/providers/provider_call.ts +433 -0
- package/src/providers/provider_reported_cost.ts +138 -0
- package/src/providers/reasoning.ts +59 -0
- package/src/providers/response_capture.ts +65 -0
- package/src/providers/stream_finalization.ts +264 -0
- package/src/providers/subscription_limits.ts +208 -0
- package/src/providers/subscription_usage.ts +99 -0
- package/src/runtime/claude_code/auxiliary_routing.ts +80 -0
- package/src/runtime/customer_disconnect.ts +66 -0
- package/src/runtime/explicit_model.ts +86 -0
- package/src/runtime/harness_identity/conversation.ts +87 -0
- package/src/runtime/harness_identity/extract.ts +323 -0
- package/src/runtime/harness_identity/index.ts +14 -0
- package/src/runtime/prepare_routed_completion.ts +224 -0
- package/src/runtime/provider_stream_lifecycle.ts +105 -0
- package/src/runtime/provider_stream_outcome.ts +83 -0
- package/src/runtime/request_tags.ts +34 -0
- package/src/runtime/routed_completion.ts +102 -0
- package/src/runtime/routed_protocol.ts +33 -0
- package/src/runtime/routed_runtime.ts +722 -0
- package/src/runtime/routing_lease.ts +273 -0
- package/src/runtime/runtime_reporter.ts +115 -0
- package/src/self_host/config.ts +173 -0
- package/src/self_host/main.ts +104 -0
- package/src/self_host/platform.ts +63 -0
- package/src/self_host/prefix_store.ts +315 -0
- package/src/self_host/resolve.ts +240 -0
- package/src/self_host/subscriptions/access.ts +43 -0
- package/src/self_host/subscriptions/http.ts +204 -0
- package/src/self_host/subscriptions/index.ts +43 -0
- package/src/self_host/subscriptions/oauth.ts +395 -0
- package/src/self_host/subscriptions/store.ts +339 -0
- package/src/strategies/auto_routing_selector.ts +72 -0
- package/src/strategies/eval_relevance.ts +57 -0
- package/src/strategies/fallback_decision.ts +30 -0
- package/src/strategies/priority_selector.ts +40 -0
- package/src/strategies/route_decision.ts +106 -0
- package/src/strategies/routing.ts +455 -0
- package/src/strategies/selector_projection.ts +207 -0
- package/src/telemetry/background.ts +40 -0
- package/src/telemetry/benchmark_replay.ts +160 -0
- package/src/telemetry/billing_finalization.ts +167 -0
- package/src/telemetry/ingest_values.ts +15 -0
- package/src/telemetry/model_cost.ts +14 -0
- package/src/telemetry/prefix_state.ts +183 -0
- package/src/telemetry/report.ts +832 -0
- package/src/telemetry/requests/interaction_observability.ts +258 -0
- package/src/telemetry/requests/retained_interaction_request.ts +20 -0
- package/src/telemetry/scrub.ts +38 -0
- package/src/telemetry/skills/claude/catalog.ts +119 -0
- package/src/telemetry/skills/claude/file_reads.ts +153 -0
- package/src/telemetry/skills/claude/observations.ts +450 -0
- package/src/telemetry/skills/codex/catalog.ts +171 -0
- package/src/telemetry/skills/codex/exec_file_reads.ts +55 -0
- package/src/telemetry/skills/codex/explicit.ts +116 -0
- package/src/telemetry/skills/codex/file_reads.ts +51 -0
- package/src/telemetry/skills/codex/identity.ts +21 -0
- package/src/telemetry/skills/observations.ts +94 -0
- package/src/telemetry/skills/paths.ts +82 -0
- package/src/telemetry/skills/pi.ts +276 -0
- package/src/telemetry/skills/shell_file_reads.ts +267 -0
- package/src/telemetry/skills/shell_words.ts +202 -0
- package/src/telemetry/tools/input.ts +16 -0
- package/src/telemetry/tools/observations.ts +349 -0
- package/src/telemetry/usage.ts +173 -0
- package/src/types.ts +150 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gatewayPlatform,
|
|
3
|
+
type OperationalErrorContext,
|
|
4
|
+
type RequestErrorContext,
|
|
5
|
+
} from "../platform/platform";
|
|
6
|
+
|
|
7
|
+
export type { OperationalErrorCode } from "../platform/platform";
|
|
8
|
+
|
|
9
|
+
export function captureRequestError(
|
|
10
|
+
error: unknown,
|
|
11
|
+
context: RequestErrorContext,
|
|
12
|
+
): void {
|
|
13
|
+
gatewayPlatform().captureRequestError(error, context);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Report failures deliberately caught outside the ingress exception path,
|
|
18
|
+
* including work after a response has started and process shutdown.
|
|
19
|
+
*/
|
|
20
|
+
export function captureOperationalError(
|
|
21
|
+
error: unknown,
|
|
22
|
+
context: OperationalErrorContext,
|
|
23
|
+
): void {
|
|
24
|
+
gatewayPlatform().captureOperationalError(error, context);
|
|
25
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Provider,
|
|
3
|
+
ReasoningEffort,
|
|
4
|
+
RoutingStrategy,
|
|
5
|
+
} from "@mupt-ai/dari-router/policy-engine";
|
|
6
|
+
import type { HarnessConversationIdentity } from "../runtime/harness_identity";
|
|
7
|
+
import type { InteractionRequest, SourceProtocol } from "../interaction/types";
|
|
8
|
+
import type { SubscriptionUsageLimit } from "../providers/subscription_limits";
|
|
9
|
+
import type {
|
|
10
|
+
ClientHarness,
|
|
11
|
+
ProviderCredential,
|
|
12
|
+
ProviderKeySource,
|
|
13
|
+
ResolvedRouter,
|
|
14
|
+
} from "../types";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Everything the gateway runtime needs from the deployment around it: router
|
|
18
|
+
* configuration and credentials, durable routing state, accounting sinks, and
|
|
19
|
+
* error reporting. The self-hosted gateway implements it with a local config
|
|
20
|
+
* file and SQLite (`self_host/`); other deployments supply their own.
|
|
21
|
+
*
|
|
22
|
+
* Methods may throw. Call sites that must not fail a served request catch,
|
|
23
|
+
* log, and continue.
|
|
24
|
+
*/
|
|
25
|
+
export type GatewayPlatform = {
|
|
26
|
+
/**
|
|
27
|
+
* Authenticate the request's key and return the router it may use, with
|
|
28
|
+
* decrypted provider credentials and the prefix-cache evidence matching
|
|
29
|
+
* `prefixHashes`. Throws HttpError(401) for an unknown key.
|
|
30
|
+
*/
|
|
31
|
+
resolveRouter(request: ResolveRouterRequest): Promise<ResolvedRouter>;
|
|
32
|
+
/**
|
|
33
|
+
* Optional. Supply the credential for one enabled model of this request,
|
|
34
|
+
* consulted after `resolveRouter` and before its provider keys (for the
|
|
35
|
+
* self-hosted gateway, its environment keys), so an embedder can serve
|
|
36
|
+
* per-tenant keys from its own store. Undefined keeps the resolved key.
|
|
37
|
+
*/
|
|
38
|
+
resolveProviderCredential?(
|
|
39
|
+
request: ProviderCredentialRequest,
|
|
40
|
+
): Promise<ProviderCredential | undefined>;
|
|
41
|
+
/** Persist one completed turn's prefix entry and/or refresh a read entry. */
|
|
42
|
+
writePrefixState(write: PrefixStateWrite): Promise<void>;
|
|
43
|
+
/** Set or clear a conversation's prefetched routing lease. */
|
|
44
|
+
writePendingLease(write: PendingLeaseWrite): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Hold an exhausted personal subscription until it resets. Resolves whether
|
|
47
|
+
* another connected subscription for the same provider can serve a retry.
|
|
48
|
+
*/
|
|
49
|
+
markSubscriptionUnavailable(hold: SubscriptionHold): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Account one call served on a platform-managed provider key. Only reached
|
|
52
|
+
* when `resolveRouter` reports a "managed" key source.
|
|
53
|
+
*/
|
|
54
|
+
recordUsage(usage: Record<string, unknown>): Promise<void>;
|
|
55
|
+
/** Receive the finished request's log row. Must not throw. */
|
|
56
|
+
recordRequest(record: RequestRecord): void;
|
|
57
|
+
captureRequestError(error: unknown, context: RequestErrorContext): void;
|
|
58
|
+
captureOperationalError(error: unknown, context: OperationalErrorContext): void;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type ResolveRouterRequest = {
|
|
62
|
+
routerId: string;
|
|
63
|
+
apiKey: string;
|
|
64
|
+
prefixHashes?: string[];
|
|
65
|
+
conversationId?: string;
|
|
66
|
+
includePublicEvalCatalog?: boolean;
|
|
67
|
+
clientHarness?: ClientHarness;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type ProviderCredentialRequest = {
|
|
71
|
+
provider: Provider;
|
|
72
|
+
model: string;
|
|
73
|
+
routerId: string;
|
|
74
|
+
organizationId: string;
|
|
75
|
+
// The gateway key the request authenticated with.
|
|
76
|
+
apiKey: string;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type PrefixStateWrite = {
|
|
80
|
+
organization_id: string;
|
|
81
|
+
router_id: string;
|
|
82
|
+
received_at: string;
|
|
83
|
+
zdr: boolean;
|
|
84
|
+
prefix_entry: Record<string, unknown> | null;
|
|
85
|
+
touched_prefix_hash: string | null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export type PendingLeaseWrite = {
|
|
89
|
+
router_id: string;
|
|
90
|
+
conversation_id: string;
|
|
91
|
+
// Conversation depth this write was decided at; writes decided shallower
|
|
92
|
+
// than the last applied one are fenced out.
|
|
93
|
+
decided_at_depth: number;
|
|
94
|
+
pending_lease: {
|
|
95
|
+
model: string;
|
|
96
|
+
reasoning_effort: string;
|
|
97
|
+
turns: number;
|
|
98
|
+
reason: string;
|
|
99
|
+
output_text: string | null;
|
|
100
|
+
} | null;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export type SubscriptionHold = {
|
|
104
|
+
userId: string;
|
|
105
|
+
credentialId: string | undefined;
|
|
106
|
+
limit: SubscriptionUsageLimit;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type RequestRecord = {
|
|
110
|
+
// The full request log row: routing decision, usage, costs, and (outside
|
|
111
|
+
// ZDR) request and response content.
|
|
112
|
+
row: Record<string, unknown>;
|
|
113
|
+
// A content-free summary of the same request.
|
|
114
|
+
summary: RequestSummary;
|
|
115
|
+
distinctId: string;
|
|
116
|
+
interaction: InteractionRequest;
|
|
117
|
+
isNewConversation: boolean;
|
|
118
|
+
zdr: boolean;
|
|
119
|
+
harnessConversationIdentity?: HarnessConversationIdentity;
|
|
120
|
+
// Parsed from the request's X-Dari-Tags header; empty when absent.
|
|
121
|
+
tags: RequestTags;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Caller-supplied attribution labels (run, trial, setting), opaque to the
|
|
125
|
+
// gateway.
|
|
126
|
+
export type RequestTags = Record<string, string>;
|
|
127
|
+
|
|
128
|
+
export type RequestSummary = {
|
|
129
|
+
request_id: string;
|
|
130
|
+
organization_id: string;
|
|
131
|
+
router_id: string;
|
|
132
|
+
api_key_id: string | null;
|
|
133
|
+
source_protocol: SourceProtocol;
|
|
134
|
+
request_kind: "user_message" | "tool_continuation" | "other";
|
|
135
|
+
status: "completed" | "provider_error" | "selector_error" | "aborted";
|
|
136
|
+
error_code: string | null;
|
|
137
|
+
stream: boolean;
|
|
138
|
+
zdr: boolean;
|
|
139
|
+
strategy: RoutingStrategy;
|
|
140
|
+
selected_model: string | null;
|
|
141
|
+
selected_provider: Provider | null;
|
|
142
|
+
selected_reasoning_effort: ReasoningEffort | null;
|
|
143
|
+
next_model: string | null;
|
|
144
|
+
next_reasoning_effort: ReasoningEffort | null;
|
|
145
|
+
fallback_model: string | null;
|
|
146
|
+
fallback_reasoning_effort: ReasoningEffort | null;
|
|
147
|
+
provider_key_source: ProviderKeySource | null;
|
|
148
|
+
message_count: number;
|
|
149
|
+
tool_count: number;
|
|
150
|
+
candidate_count: number;
|
|
151
|
+
provider_attempt_count: number;
|
|
152
|
+
prefix_match_depth: number | null;
|
|
153
|
+
prefix_warm_tokens: number | null;
|
|
154
|
+
selector_latency_ms: number | null;
|
|
155
|
+
provider_latency_ms: number | null;
|
|
156
|
+
total_latency_ms: number;
|
|
157
|
+
input_tokens: number | null;
|
|
158
|
+
cache_read_tokens: number | null;
|
|
159
|
+
cache_write_tokens: number | null;
|
|
160
|
+
output_tokens: number | null;
|
|
161
|
+
total_tokens: number | null;
|
|
162
|
+
// Provider-reported cost when the provider returns one (OpenRouter, Vercel
|
|
163
|
+
// AI Gateway), otherwise priced from the model's rates when known.
|
|
164
|
+
total_cost_usd: number | null;
|
|
165
|
+
cost_source: "provider" | "pricing" | null;
|
|
166
|
+
pricing_known: boolean | null;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export type RequestErrorContext = {
|
|
170
|
+
request: Request;
|
|
171
|
+
routerId: string;
|
|
172
|
+
requestId?: string;
|
|
173
|
+
sourceProtocol: SourceProtocol | "openai_models" | "anthropic_models";
|
|
174
|
+
status: number;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export type OperationalErrorCode =
|
|
178
|
+
| "background_drain_timeout"
|
|
179
|
+
| "billing_usage_report_failed"
|
|
180
|
+
| "routing_report_assembly_failed"
|
|
181
|
+
| "routing_report_barrier_failed"
|
|
182
|
+
| "server_force_stop_failed"
|
|
183
|
+
| "stream_report_finalization_failed"
|
|
184
|
+
| "subscription_unavailable_ingest_failed";
|
|
185
|
+
|
|
186
|
+
export type OperationalErrorContext = {
|
|
187
|
+
code: OperationalErrorCode;
|
|
188
|
+
requestId?: string;
|
|
189
|
+
routerId?: string;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
let bound: GatewayPlatform | null = null;
|
|
193
|
+
|
|
194
|
+
/** Bind the platform every request uses. The latest binding wins. */
|
|
195
|
+
export function bindGatewayPlatform(platform: GatewayPlatform): void {
|
|
196
|
+
bound = platform;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function gatewayPlatform(): GatewayPlatform {
|
|
200
|
+
if (bound === null) {
|
|
201
|
+
throw new Error("No gateway platform is bound; create the request handler first.");
|
|
202
|
+
}
|
|
203
|
+
return bound;
|
|
204
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Stable public identity for the standard /v1 router. Platforms resolve it
|
|
2
|
+
// to the caller's default router.
|
|
3
|
+
export const DEFAULT_ROUTER_ALIAS = "default";
|
|
4
|
+
|
|
5
|
+
// The most prefix hashes one router resolution looks up.
|
|
6
|
+
export const ROUTING_PREFIX_HASHES_MAX_COUNT = 200;
|