dsh-antigravity-auth 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/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/README.zh.md +159 -0
- package/cordis.patch.yml +12 -0
- package/lib/capability-lifecycle--tgGKajs.js +1896 -0
- package/lib/client.cjs +2123 -0
- package/lib/client.cjs.map +1 -0
- package/lib/image.js +564 -0
- package/lib/index.js +176 -0
- package/lib/invariant.js +2 -0
- package/lib/live-gate-runner.js +542 -0
- package/lib/live-gates.js +97 -0
- package/lib/llm-adapter.js +916 -0
- package/lib/media-admission.js +206 -0
- package/lib/private-failure-B9vzUkQ7.js +23 -0
- package/lib/private-transport-urF138qW.js +641 -0
- package/lib/private-transport.js +2 -0
- package/lib/project-context.js +133 -0
- package/lib/quota.js +283 -0
- package/lib/replay.js +156 -0
- package/lib/rpc-contract-BFWfdKKs.js +491 -0
- package/lib/rpc-contract.js +2 -0
- package/lib/safe-text-AlEyN8q_.js +12 -0
- package/lib/search.js +259 -0
- package/lib/status-D0-em3Ru.js +125 -0
- package/lib/types/auth-service.d.ts +64 -0
- package/lib/types/auth-service.d.ts.map +1 -0
- package/lib/types/auth-store.d.ts +45 -0
- package/lib/types/auth-store.d.ts.map +1 -0
- package/lib/types/bootstrap-service.d.ts +6 -0
- package/lib/types/bootstrap-service.d.ts.map +1 -0
- package/lib/types/capability-gates.d.ts +19 -0
- package/lib/types/capability-gates.d.ts.map +1 -0
- package/lib/types/capability-lifecycle.d.ts +26 -0
- package/lib/types/capability-lifecycle.d.ts.map +1 -0
- package/lib/types/client/AntigravityAuthSettings.d.ts +19 -0
- package/lib/types/client/AntigravityAuthSettings.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +121 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/styles.d.ts +4 -0
- package/lib/types/client/styles.d.ts.map +1 -0
- package/lib/types/credential-coordinator.d.ts +84 -0
- package/lib/types/credential-coordinator.d.ts.map +1 -0
- package/lib/types/image.d.ts +39 -0
- package/lib/types/image.d.ts.map +1 -0
- package/lib/types/index.d.ts +21 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/invariant.d.ts +3 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/live-gate-attachments.d.ts +6 -0
- package/lib/types/live-gate-attachments.d.ts.map +1 -0
- package/lib/types/live-gate-auth.d.ts +5 -0
- package/lib/types/live-gate-auth.d.ts.map +1 -0
- package/lib/types/live-gate-image.d.ts +5 -0
- package/lib/types/live-gate-image.d.ts.map +1 -0
- package/lib/types/live-gate-llm.d.ts +10 -0
- package/lib/types/live-gate-llm.d.ts.map +1 -0
- package/lib/types/live-gate-outcome.d.ts +8 -0
- package/lib/types/live-gate-outcome.d.ts.map +1 -0
- package/lib/types/live-gate-runner.d.ts +15 -0
- package/lib/types/live-gate-runner.d.ts.map +1 -0
- package/lib/types/live-gate-search.d.ts +5 -0
- package/lib/types/live-gate-search.d.ts.map +1 -0
- package/lib/types/live-gate-video.d.ts +8 -0
- package/lib/types/live-gate-video.d.ts.map +1 -0
- package/lib/types/live-gates.d.ts +25 -0
- package/lib/types/live-gates.d.ts.map +1 -0
- package/lib/types/llm-adapter.d.ts +65 -0
- package/lib/types/llm-adapter.d.ts.map +1 -0
- package/lib/types/login-types.d.ts +36 -0
- package/lib/types/login-types.d.ts.map +1 -0
- package/lib/types/media-admission.d.ts +54 -0
- package/lib/types/media-admission.d.ts.map +1 -0
- package/lib/types/model-catalog.d.ts +19 -0
- package/lib/types/model-catalog.d.ts.map +1 -0
- package/lib/types/oauth-flow.d.ts +87 -0
- package/lib/types/oauth-flow.d.ts.map +1 -0
- package/lib/types/private-failure.d.ts +6 -0
- package/lib/types/private-failure.d.ts.map +1 -0
- package/lib/types/private-transport-error.d.ts +13 -0
- package/lib/types/private-transport-error.d.ts.map +1 -0
- package/lib/types/private-transport.d.ts +48 -0
- package/lib/types/private-transport.d.ts.map +1 -0
- package/lib/types/project-context.d.ts +30 -0
- package/lib/types/project-context.d.ts.map +1 -0
- package/lib/types/quota.d.ts +43 -0
- package/lib/types/quota.d.ts.map +1 -0
- package/lib/types/raw-http.d.ts +11 -0
- package/lib/types/raw-http.d.ts.map +1 -0
- package/lib/types/replay.d.ts +30 -0
- package/lib/types/replay.d.ts.map +1 -0
- package/lib/types/rpc-contract.d.ts +33 -0
- package/lib/types/rpc-contract.d.ts.map +1 -0
- package/lib/types/rpc-vocabulary.d.ts +7 -0
- package/lib/types/rpc-vocabulary.d.ts.map +1 -0
- package/lib/types/rpc.d.ts +11 -0
- package/lib/types/rpc.d.ts.map +1 -0
- package/lib/types/safe-text.d.ts +3 -0
- package/lib/types/safe-text.d.ts.map +1 -0
- package/lib/types/search.d.ts +42 -0
- package/lib/types/search.d.ts.map +1 -0
- package/lib/types/status.d.ts +62 -0
- package/lib/types/status.d.ts.map +1 -0
- package/lib/types/video.d.ts +42 -0
- package/lib/types/video.d.ts.map +1 -0
- package/lib/types/wire-identity.d.ts +49 -0
- package/lib/types/wire-identity.d.ts.map +1 -0
- package/lib/video.js +320 -0
- package/lib/wire-identity.js +162 -0
- package/package.json +189 -0
- package/scripts/live-gates.mjs +4 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Gated workspace-video understanding proof of concept. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import z from '@deepseek-ai/schemastery';
|
|
4
|
+
import type { FileSystem } from '@deepseek-ai/dsh-fs';
|
|
5
|
+
import { HarnessError } from '@deepseek-ai/dsh-llm';
|
|
6
|
+
import type { TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
7
|
+
import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
8
|
+
import type { CredentialCoordinator, HostCredential } from './credential-coordinator.ts';
|
|
9
|
+
import { type PrivateTransport } from './private-transport.ts';
|
|
10
|
+
export declare const name = "antigravity-video";
|
|
11
|
+
export declare const inject: string[];
|
|
12
|
+
export declare const ANALYZE_VIDEO_TOOL_NAME = "analyze_video";
|
|
13
|
+
export declare const UNDERSTAND_VIDEO_TOOL_NAME = "analyze_video";
|
|
14
|
+
export declare const ANTIGRAVITY_VIDEO_ENDPOINT: `${string}/v1internal:generateContent`;
|
|
15
|
+
export declare const ANTIGRAVITY_VIDEO_MODEL = "antigravity-gemini-3.7-flash";
|
|
16
|
+
export declare const ANTIGRAVITY_VIDEO_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
|
|
17
|
+
export interface AntigravityVideoSettings {
|
|
18
|
+
readonly enabled: boolean;
|
|
19
|
+
readonly model: string;
|
|
20
|
+
readonly maxBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface Config extends AntigravityVideoSettings {
|
|
23
|
+
}
|
|
24
|
+
export declare const Config: z<Config>;
|
|
25
|
+
export interface AntigravityVideoToolOptions {
|
|
26
|
+
readonly auth: Pick<CredentialCoordinator, 'credential'> | {
|
|
27
|
+
credential(signal?: AbortSignal): Promise<HostCredential | undefined>;
|
|
28
|
+
};
|
|
29
|
+
readonly fs: Pick<FileSystem, 'resolve' | 'contains' | 'readBytes' | 'lstat' | 'stat'>;
|
|
30
|
+
readonly settings?: () => AntigravityVideoSettings;
|
|
31
|
+
readonly transport?: PrivateTransport;
|
|
32
|
+
}
|
|
33
|
+
export declare class AntigravityVideoError extends HarnessError {
|
|
34
|
+
}
|
|
35
|
+
export interface VideoAnalysisResult {
|
|
36
|
+
readonly text: string;
|
|
37
|
+
readonly usage?: TokenUsage;
|
|
38
|
+
}
|
|
39
|
+
export declare function createAntigravityVideoTools(options: AntigravityVideoToolOptions): readonly ToolDefinition[];
|
|
40
|
+
export declare function buildVideoPayload(prompt: string, model: string, credential: Pick<HostCredential, 'projectId'>, data: Uint8Array): Record<string, unknown>;
|
|
41
|
+
export declare function apply(ctx?: Context, config?: Config): void;
|
|
42
|
+
//# sourceMappingURL=video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/video.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAG5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAkB,cAAc,EAAkB,MAAM,wBAAwB,CAAA;AAG5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACxF,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAA;AAM/B,eAAO,MAAM,IAAI,sBAAsB,CAAA;AACvC,eAAO,MAAM,MAAM,UAAqC,CAAA;AACxD,eAAO,MAAM,uBAAuB,kBAAkB,CAAA;AACtD,eAAO,MAAM,0BAA0B,kBAA0B,CAAA;AACjE,eAAO,MAAM,0BAA0B,wCAAmE,CAAA;AAC1G,eAAO,MAAM,uBAAuB,iCAAiC,CAAA;AACrE,eAAO,MAAM,oCAAoC,uDAAyC,CAAA;AAE1F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,MAAO,SAAQ,wBAAwB;CAAG;AAE3D,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAI3B,CAAA;AAEF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,GAAG;QAAE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAA;KAAE,CAAA;IACpI,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC,CAAA;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAA;IAClD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;CACtC;AAED,qBAAa,qBAAsB,SAAQ,YAAY;CAAG;AAE1D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,2BAA2B,GAAG,SAAS,cAAc,EAAE,CA0B3G;AAmCD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAC7C,IAAI,EAAE,UAAU,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAED,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,GAAE,MAAsF,GAAG,IAAI,CA4BzI"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The only identity seam for Antigravity private requests.
|
|
3
|
+
*
|
|
4
|
+
* The community transport snapshot owns the audited provider framing. This
|
|
5
|
+
* module owns the provider headers that identify that framing and carries the
|
|
6
|
+
* truthful DSH application identity in a plugin-owned secondary header. No
|
|
7
|
+
* caller may supply, suppress, rename, or replace either identity.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DSH_ATTRIBUTION_HEADER: "X-DeepSeek-Harness-Attribution";
|
|
10
|
+
export declare const AGY_PROVIDER_USER_AGENT: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/1.18.3 Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36";
|
|
11
|
+
export declare const ANTIGRAVITY_WIRE_ORIGIN: string;
|
|
12
|
+
export declare const ANTIGRAVITY_WIRE_ORIGINS: readonly string[];
|
|
13
|
+
export declare const ANTIGRAVITY_WIRE_PATHS: readonly string[];
|
|
14
|
+
export type WireHeaderPair = readonly [name: string, value: string];
|
|
15
|
+
export interface WireIdentityHeaders {
|
|
16
|
+
readonly 'User-Agent': string;
|
|
17
|
+
readonly 'X-Goog-Api-Client': string;
|
|
18
|
+
readonly 'Client-Metadata': string;
|
|
19
|
+
readonly [DSH_ATTRIBUTION_HEADER]: string;
|
|
20
|
+
}
|
|
21
|
+
export interface WireRequest {
|
|
22
|
+
/** Host-only OAuth access token; it is never included in an error message. */
|
|
23
|
+
readonly authorization: string;
|
|
24
|
+
/** JSON request bytes. The community framing decides length vs chunked encoding. */
|
|
25
|
+
readonly body: string | Uint8Array;
|
|
26
|
+
}
|
|
27
|
+
export declare class WireIdentityError extends Error {
|
|
28
|
+
readonly code: string;
|
|
29
|
+
constructor(code: string, message: string);
|
|
30
|
+
}
|
|
31
|
+
/** Build the fixed provider identity plus the one required DSH carrier. */
|
|
32
|
+
export declare function buildWireIdentityHeaders(): WireIdentityHeaders;
|
|
33
|
+
export interface WireIdentity {
|
|
34
|
+
/** The immutable provider and secondary attribution headers. */
|
|
35
|
+
headers(): WireIdentityHeaders;
|
|
36
|
+
/**
|
|
37
|
+
* Build the exact header sequence used by the audited HTTP/1.1 framing.
|
|
38
|
+
* The caller supplies only the endpoint, bearer value, and body; arbitrary
|
|
39
|
+
* header injection is intentionally not part of this interface.
|
|
40
|
+
*/
|
|
41
|
+
headerPairs(url: string, request: WireRequest): readonly WireHeaderPair[];
|
|
42
|
+
/** Serialize the provider-fixed request as literal HTTP/1.1 bytes. */
|
|
43
|
+
serialize(url: string, request: WireRequest): Uint8Array;
|
|
44
|
+
}
|
|
45
|
+
/** Create one immutable identity policy for all private operation callers. */
|
|
46
|
+
export declare function createWireIdentity(): WireIdentity;
|
|
47
|
+
/** Validate one complete, provider-fixed Wire Identity header set. */
|
|
48
|
+
export declare function assertWireIdentityInvariant(value: unknown): asserts value is WireIdentityHeaders;
|
|
49
|
+
//# sourceMappingURL=wire-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-identity.d.ts","sourceRoot":"","sources":["../../src/wire-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,eAAO,MAAM,sBAAsB,EAAG,gCAAyC,CAAA;AAC/E,eAAO,MAAM,uBAAuB,2JAAoC,CAAA;AACxE,eAAO,MAAM,uBAAuB,QAAuC,CAAA;AAC3E,eAAO,MAAM,wBAAwB,mBAGnC,CAAA;AACF,eAAO,MAAM,sBAAsB,mBAMjC,CAAA;AAKF,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAEnE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;IACpC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;CACnC;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;gBAET,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAED,2EAA2E;AAC3E,wBAAgB,wBAAwB,IAAI,mBAAmB,CAY9D;AAED,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,OAAO,IAAI,mBAAmB,CAAA;IAC9B;;;;OAIG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,cAAc,EAAE,CAAA;IACzE,sEAAsE;IACtE,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAAA;CACzD;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,IAAI,YAAY,CAiDjD;AAED,sEAAsE;AACtE,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,mBAAmB,CA2BhG"}
|
package/lib/video.js
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { i as createAntigravityAuthService, t as mountCapabilityLifecycle } from "./capability-lifecycle--tgGKajs.js";
|
|
2
|
+
import { d as privateStatusError, i as DEFAULT_PRIVATE_RESPONSE_BYTES, l as createPrivateTransport, m as PrivateTransportError, p as readPrivateText } from "./private-transport-urF138qW.js";
|
|
3
|
+
import { ANTIGRAVITY_WIRE_ORIGIN } from "./wire-identity.js";
|
|
4
|
+
import { t as classifyPrivateFailure } from "./private-failure-B9vzUkQ7.js";
|
|
5
|
+
import { admitWorkspaceVideo } from "./media-admission.js";
|
|
6
|
+
import { resolveModelWithTier } from "@cortexkit/antigravity-auth-core";
|
|
7
|
+
import { Buffer } from "node:buffer";
|
|
8
|
+
import { HarnessError } from "@deepseek-ai/dsh-llm";
|
|
9
|
+
import z from "@deepseek-ai/schemastery";
|
|
10
|
+
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
11
|
+
//#region src/video.ts
|
|
12
|
+
/** Gated workspace-video understanding proof of concept. */
|
|
13
|
+
const name = "antigravity-video";
|
|
14
|
+
const inject = [
|
|
15
|
+
"tools",
|
|
16
|
+
"fs",
|
|
17
|
+
"antigravityAuth"
|
|
18
|
+
];
|
|
19
|
+
const ANALYZE_VIDEO_TOOL_NAME = "analyze_video";
|
|
20
|
+
const UNDERSTAND_VIDEO_TOOL_NAME = ANALYZE_VIDEO_TOOL_NAME;
|
|
21
|
+
const ANTIGRAVITY_VIDEO_ENDPOINT = `${ANTIGRAVITY_WIRE_ORIGIN}/v1internal:generateContent`;
|
|
22
|
+
const ANTIGRAVITY_VIDEO_MODEL = "antigravity-gemini-3.7-flash";
|
|
23
|
+
const ANTIGRAVITY_VIDEO_SETTINGS_NAMESPACE = settingsNamespace("antigravity-video");
|
|
24
|
+
const Config = z.object({
|
|
25
|
+
enabled: z.boolean().default(true),
|
|
26
|
+
model: z.string().default(ANTIGRAVITY_VIDEO_MODEL),
|
|
27
|
+
maxBytes: z.number().step(1).min(1).max(33554432).default(33554432)
|
|
28
|
+
});
|
|
29
|
+
var AntigravityVideoError = class extends HarnessError {};
|
|
30
|
+
function createAntigravityVideoTools(options) {
|
|
31
|
+
const fixedOptions = {
|
|
32
|
+
...options,
|
|
33
|
+
transport: options.transport ?? createPrivateTransport({ maxRequestBytes: 50331648 })
|
|
34
|
+
};
|
|
35
|
+
return [{
|
|
36
|
+
name: ANALYZE_VIDEO_TOOL_NAME,
|
|
37
|
+
description: "Analyze an explicit MP4 file inside the active workspace with the gated Antigravity video POC.",
|
|
38
|
+
parameters: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
path: {
|
|
42
|
+
type: "string",
|
|
43
|
+
minLength: 1,
|
|
44
|
+
maxLength: 4096
|
|
45
|
+
},
|
|
46
|
+
prompt: {
|
|
47
|
+
type: "string",
|
|
48
|
+
minLength: 1,
|
|
49
|
+
maxLength: 16384
|
|
50
|
+
},
|
|
51
|
+
model: {
|
|
52
|
+
type: "string",
|
|
53
|
+
maxLength: 256
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
required: ["path", "prompt"],
|
|
57
|
+
additionalProperties: false
|
|
58
|
+
},
|
|
59
|
+
output: {
|
|
60
|
+
schema: videoSchema,
|
|
61
|
+
render: (_args, value) => [{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: value.text
|
|
64
|
+
}],
|
|
65
|
+
presentationMeta: (_args, value) => value
|
|
66
|
+
},
|
|
67
|
+
execute: async (args, exec) => executeVideo(fixedOptions, args, exec),
|
|
68
|
+
isConcurrencySafe: () => false
|
|
69
|
+
}];
|
|
70
|
+
}
|
|
71
|
+
async function executeVideo(options, rawArgs, exec) {
|
|
72
|
+
const settings = options.settings?.() ?? {
|
|
73
|
+
enabled: true,
|
|
74
|
+
model: "antigravity-gemini-3.7-flash"
|
|
75
|
+
};
|
|
76
|
+
if (!settings.enabled) throw new AntigravityVideoError("Antigravity Video is disabled by its capability gate", "VIDEO_DISABLED");
|
|
77
|
+
const args = parseArgs(rawArgs, settings);
|
|
78
|
+
const agent = requireAgent(exec);
|
|
79
|
+
const credential = await options.auth.credential(exec.signal);
|
|
80
|
+
if (credential === void 0) throw new AntigravityVideoError("Antigravity Video requires a logged-in account", "VIDEO_AUTH_REQUIRED");
|
|
81
|
+
const cwd = workspaceCwd(agent);
|
|
82
|
+
const admitted = await admitWorkspaceVideo({
|
|
83
|
+
fs: options.fs,
|
|
84
|
+
...settings.maxBytes === void 0 ? {} : { maxVideoBytes: settings.maxBytes }
|
|
85
|
+
}, cwd, args.path, exec.signal);
|
|
86
|
+
const transport = options.transport;
|
|
87
|
+
if (transport === void 0) throw new AntigravityVideoError("The Antigravity Video transport is unavailable", "VIDEO_FAILED");
|
|
88
|
+
let response;
|
|
89
|
+
try {
|
|
90
|
+
response = await transport.request({
|
|
91
|
+
url: ANTIGRAVITY_VIDEO_ENDPOINT,
|
|
92
|
+
accessToken: credential.accessToken,
|
|
93
|
+
body: JSON.stringify(buildVideoPayload(args.prompt, args.model, credential, admitted.data)),
|
|
94
|
+
signal: exec.signal
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw toVideoError(error);
|
|
98
|
+
}
|
|
99
|
+
const statusError = privateStatusError(response.status);
|
|
100
|
+
if (statusError !== void 0) {
|
|
101
|
+
await response.body?.cancel().catch(() => {});
|
|
102
|
+
throw toVideoError(statusError);
|
|
103
|
+
}
|
|
104
|
+
let value;
|
|
105
|
+
try {
|
|
106
|
+
value = JSON.parse(await readPrivateText(response, {
|
|
107
|
+
signal: exec.signal,
|
|
108
|
+
maxBytes: DEFAULT_PRIVATE_RESPONSE_BYTES
|
|
109
|
+
}));
|
|
110
|
+
} catch (error) {
|
|
111
|
+
throw toVideoError(error);
|
|
112
|
+
}
|
|
113
|
+
const text = extractText(value);
|
|
114
|
+
if (text === void 0) throw new AntigravityVideoError("Antigravity Video returned no text understanding", "VIDEO_RESPONSE_EMPTY");
|
|
115
|
+
const usage = extractUsage(value);
|
|
116
|
+
return {
|
|
117
|
+
text,
|
|
118
|
+
...usage === void 0 ? {} : { usage }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function buildVideoPayload(prompt, model, credential, data) {
|
|
122
|
+
const project = credential.projectId === "inductive-dreamer-qrkws" || !credential.projectId ? void 0 : credential.projectId;
|
|
123
|
+
const resolved = resolveModelWithTier(model, { cli_first: false });
|
|
124
|
+
const wireModel = resolved.actualModel.startsWith("gemini-3.7-flash") ? "gemini-3-flash" : resolved.actualModel;
|
|
125
|
+
return {
|
|
126
|
+
...project === void 0 ? {} : { project },
|
|
127
|
+
model: wireModel,
|
|
128
|
+
request: { contents: [{
|
|
129
|
+
role: "user",
|
|
130
|
+
parts: [{ text: prompt }, { inlineData: {
|
|
131
|
+
mimeType: "video/mp4",
|
|
132
|
+
data: Buffer.from(data).toString("base64")
|
|
133
|
+
} }]
|
|
134
|
+
}] }
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function apply(ctx, config = {
|
|
138
|
+
enabled: true,
|
|
139
|
+
model: ANTIGRAVITY_VIDEO_MODEL,
|
|
140
|
+
maxBytes: 33554432
|
|
141
|
+
}) {
|
|
142
|
+
if (ctx === void 0) return;
|
|
143
|
+
const candidate = ctx;
|
|
144
|
+
if (candidate.tools === void 0 || candidate.fs === void 0) return;
|
|
145
|
+
let current = () => config;
|
|
146
|
+
let lifecycle;
|
|
147
|
+
installSettingsSection(ctx, ANTIGRAVITY_VIDEO_SETTINGS_NAMESPACE, Config, config, {
|
|
148
|
+
setSource: (source) => {
|
|
149
|
+
current = source;
|
|
150
|
+
lifecycle?.sync();
|
|
151
|
+
},
|
|
152
|
+
onChange: () => {
|
|
153
|
+
lifecycle?.sync();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const provided = candidate.get?.("antigravityAuth");
|
|
157
|
+
const auth = isAuthService(provided) ? provided : createAntigravityAuthService();
|
|
158
|
+
lifecycle = mountCapabilityLifecycle({
|
|
159
|
+
ctx,
|
|
160
|
+
auth,
|
|
161
|
+
id: "video",
|
|
162
|
+
enabled: () => current().enabled,
|
|
163
|
+
register: () => {
|
|
164
|
+
const disposers = createAntigravityVideoTools({
|
|
165
|
+
auth,
|
|
166
|
+
fs: candidate.fs,
|
|
167
|
+
settings: current
|
|
168
|
+
}).map((tool) => candidate.tools.register(tool));
|
|
169
|
+
return () => {
|
|
170
|
+
for (const dispose of disposers.reverse()) dispose();
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
ownsAuth: auth !== provided,
|
|
174
|
+
label: "antigravity-video: tool lifecycle"
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function isAuthService(value) {
|
|
178
|
+
return isRecord(value) && typeof value.credential === "function" && typeof value.status === "function";
|
|
179
|
+
}
|
|
180
|
+
function extractText(value) {
|
|
181
|
+
const output = [];
|
|
182
|
+
let outputLength = 0;
|
|
183
|
+
const visit = (item, depth = 0) => {
|
|
184
|
+
if (depth > 32 || outputLength >= 65536) return;
|
|
185
|
+
if (Array.isArray(item)) {
|
|
186
|
+
for (const child of item) visit(child, depth + 1);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (!isRecord(item)) return;
|
|
190
|
+
if (Array.isArray(item.parts)) for (const part of item.parts) {
|
|
191
|
+
if (!isRecord(part) || typeof part.text !== "string" || hasControl(part.text)) continue;
|
|
192
|
+
const text = part.text.slice(0, 65536 - outputLength);
|
|
193
|
+
output.push(text);
|
|
194
|
+
outputLength += text.length;
|
|
195
|
+
}
|
|
196
|
+
if (isRecord(item.response)) visit(item.response, depth + 1);
|
|
197
|
+
if (isRecord(item.content)) visit(item.content, depth + 1);
|
|
198
|
+
if (Array.isArray(item.candidates)) visit(item.candidates, depth + 1);
|
|
199
|
+
if (isRecord(item.serverContent)) visit(item.serverContent, depth + 1);
|
|
200
|
+
if (isRecord(item.modelTurn)) visit(item.modelTurn, depth + 1);
|
|
201
|
+
};
|
|
202
|
+
visit(value);
|
|
203
|
+
const text = output.join("").trim();
|
|
204
|
+
return text.length === 0 ? void 0 : text.slice(0, 65536);
|
|
205
|
+
}
|
|
206
|
+
function extractUsage(value) {
|
|
207
|
+
const visit = (item, depth = 0) => {
|
|
208
|
+
if (depth > 32) return void 0;
|
|
209
|
+
if (Array.isArray(item)) {
|
|
210
|
+
for (const child of item) {
|
|
211
|
+
const result = visit(child, depth + 1);
|
|
212
|
+
if (result !== void 0) return result;
|
|
213
|
+
}
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (!isRecord(item)) return void 0;
|
|
217
|
+
const raw = isRecord(item.usageMetadata) ? item.usageMetadata : isRecord(item.usage_metadata) ? item.usage_metadata : isRecord(item.usage) ? item.usage : void 0;
|
|
218
|
+
if (raw !== void 0) {
|
|
219
|
+
const input = safeCount(raw.promptTokenCount ?? raw.inputTokenCount);
|
|
220
|
+
const output = safeCount(raw.candidatesTokenCount ?? raw.outputTokenCount);
|
|
221
|
+
const cached = safeCount(raw.cachedContentTokenCount ?? raw.cacheReadTokens);
|
|
222
|
+
const reasoning = safeCount(raw.thoughtsTokenCount ?? raw.reasoningTokenCount);
|
|
223
|
+
if (input !== void 0 || output !== void 0 || cached !== void 0 || reasoning !== void 0) return {
|
|
224
|
+
inputTokens: input ?? 0,
|
|
225
|
+
outputTokens: output ?? 0,
|
|
226
|
+
...cached === void 0 ? {} : { cacheReadTokens: cached },
|
|
227
|
+
...reasoning === void 0 ? {} : { reasoningTokens: reasoning }
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
for (const key of [
|
|
231
|
+
"response",
|
|
232
|
+
"candidates",
|
|
233
|
+
"serverContent"
|
|
234
|
+
]) {
|
|
235
|
+
const result = visit(item[key], depth + 1);
|
|
236
|
+
if (result !== void 0) return result;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
return visit(value);
|
|
240
|
+
}
|
|
241
|
+
function safeCount(value) {
|
|
242
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
243
|
+
}
|
|
244
|
+
function parseArgs(value, settings) {
|
|
245
|
+
if (!isRecord(value) || hasExtra(value, [
|
|
246
|
+
"path",
|
|
247
|
+
"prompt",
|
|
248
|
+
"model"
|
|
249
|
+
]) || typeof value.path !== "string" || typeof value.prompt !== "string" || value.path.length === 0 || value.path.length > 4096 || value.prompt.trim().length === 0 || value.prompt.length > 16384) throw new AntigravityVideoError("analyze_video expects a closed path and prompt object", "INVALID_ARGS");
|
|
250
|
+
const model = value.model === void 0 ? settings.model : value.model;
|
|
251
|
+
if (typeof model !== "string" || model.trim().length === 0 || model.length > 256) throw new AntigravityVideoError("The video model is invalid", "INVALID_ARGS");
|
|
252
|
+
return {
|
|
253
|
+
path: value.path,
|
|
254
|
+
prompt: value.prompt.trim().slice(0, 16384),
|
|
255
|
+
model: model.trim()
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function requireAgent(exec) {
|
|
259
|
+
if (exec.agent === void 0) throw new AntigravityVideoError("Video analysis requires an active workspace", "VIDEO_WORKSPACE_REQUIRED");
|
|
260
|
+
workspaceCwd(exec.agent);
|
|
261
|
+
return exec.agent;
|
|
262
|
+
}
|
|
263
|
+
function workspaceCwd(agent) {
|
|
264
|
+
const cwd = agent.session.header.cwd;
|
|
265
|
+
if (typeof cwd !== "string" || cwd.length === 0) throw new AntigravityVideoError("Video analysis requires an active workspace", "VIDEO_WORKSPACE_REQUIRED");
|
|
266
|
+
return cwd;
|
|
267
|
+
}
|
|
268
|
+
const VIDEO_FAILURE_CODES = {
|
|
269
|
+
authentication: "VIDEO_AUTH_REQUIRED",
|
|
270
|
+
forbidden: "VIDEO_FORBIDDEN",
|
|
271
|
+
"rate-limited": "VIDEO_RATE_LIMITED",
|
|
272
|
+
cancelled: "VIDEO_CANCELLED",
|
|
273
|
+
timeout: "VIDEO_TIMEOUT",
|
|
274
|
+
"attribution-rejected": "VIDEO_PROTOCOL_DRIFT",
|
|
275
|
+
"protocol-drift": "VIDEO_PROTOCOL_DRIFT",
|
|
276
|
+
"response-limit": "VIDEO_PROTOCOL_DRIFT",
|
|
277
|
+
"request-limit": "VIDEO_PROTOCOL_DRIFT",
|
|
278
|
+
upstream: "VIDEO_FAILED",
|
|
279
|
+
network: "VIDEO_FAILED",
|
|
280
|
+
failed: "VIDEO_FAILED"
|
|
281
|
+
};
|
|
282
|
+
function toVideoError(error) {
|
|
283
|
+
if (error instanceof AntigravityVideoError) return error;
|
|
284
|
+
if (error instanceof PrivateTransportError) return new AntigravityVideoError("The Antigravity Video request failed safely", VIDEO_FAILURE_CODES[classifyPrivateFailure(error)]);
|
|
285
|
+
return new AntigravityVideoError("The Antigravity Video request failed safely", "VIDEO_FAILED");
|
|
286
|
+
}
|
|
287
|
+
function hasControl(value) {
|
|
288
|
+
for (const character of value) {
|
|
289
|
+
const code = character.charCodeAt(0);
|
|
290
|
+
if (code < 32 || code === 127) return true;
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
function hasExtra(value, allowed) {
|
|
295
|
+
return Object.keys(value).some((key) => !allowed.includes(key));
|
|
296
|
+
}
|
|
297
|
+
function isRecord(value) {
|
|
298
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
299
|
+
}
|
|
300
|
+
const videoSchema = {
|
|
301
|
+
type: "object",
|
|
302
|
+
properties: {
|
|
303
|
+
text: { type: "string" },
|
|
304
|
+
usage: {
|
|
305
|
+
type: "object",
|
|
306
|
+
properties: {
|
|
307
|
+
inputTokens: { type: "integer" },
|
|
308
|
+
outputTokens: { type: "integer" },
|
|
309
|
+
cacheReadTokens: { type: "integer" },
|
|
310
|
+
reasoningTokens: { type: "integer" }
|
|
311
|
+
},
|
|
312
|
+
required: ["inputTokens", "outputTokens"],
|
|
313
|
+
additionalProperties: false
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
required: ["text"],
|
|
317
|
+
additionalProperties: false
|
|
318
|
+
};
|
|
319
|
+
//#endregion
|
|
320
|
+
export { ANALYZE_VIDEO_TOOL_NAME, ANTIGRAVITY_VIDEO_ENDPOINT, ANTIGRAVITY_VIDEO_MODEL, ANTIGRAVITY_VIDEO_SETTINGS_NAMESPACE, AntigravityVideoError, Config, UNDERSTAND_VIDEO_TOOL_NAME, apply, buildVideoPayload, createAntigravityVideoTools, inject, name };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { ANTIGRAVITY_ENDPOINT, ANTIGRAVITY_ENDPOINT_PROD, ANTIGRAVITY_HEADERS, buildAgyCliHeaderPairs } from "@cortexkit/antigravity-auth-core";
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
import { attributionHeaders } from "@deepseek-ai/dsh-llm";
|
|
4
|
+
//#region src/wire-identity.ts
|
|
5
|
+
/**
|
|
6
|
+
* The only identity seam for Antigravity private requests.
|
|
7
|
+
*
|
|
8
|
+
* The community transport snapshot owns the audited provider framing. This
|
|
9
|
+
* module owns the provider headers that identify that framing and carries the
|
|
10
|
+
* truthful DSH application identity in a plugin-owned secondary header. No
|
|
11
|
+
* caller may supply, suppress, rename, or replace either identity.
|
|
12
|
+
*/
|
|
13
|
+
const DSH_ATTRIBUTION_HEADER = "X-DeepSeek-Harness-Attribution";
|
|
14
|
+
const AGY_PROVIDER_USER_AGENT = ANTIGRAVITY_HEADERS["User-Agent"];
|
|
15
|
+
const ANTIGRAVITY_WIRE_ORIGIN = new URL(ANTIGRAVITY_ENDPOINT).origin;
|
|
16
|
+
const ANTIGRAVITY_WIRE_ORIGINS = Object.freeze([new URL(ANTIGRAVITY_ENDPOINT).origin, new URL(ANTIGRAVITY_ENDPOINT_PROD).origin]);
|
|
17
|
+
const ANTIGRAVITY_WIRE_PATHS = Object.freeze([
|
|
18
|
+
"/v1internal:loadCodeAssist",
|
|
19
|
+
"/v1internal:streamGenerateContent",
|
|
20
|
+
"/v1internal:generateContent",
|
|
21
|
+
"/v1internal:retrieveUserQuotaSummary",
|
|
22
|
+
"/v1internal:fetchAvailableModels"
|
|
23
|
+
]);
|
|
24
|
+
const MAX_HEADER_VALUE_LENGTH = 1024;
|
|
25
|
+
const ATTRIBUTION_KEYS = /* @__PURE__ */ new Set(["user-agent", "User-Agent"]);
|
|
26
|
+
var WireIdentityError = class extends Error {
|
|
27
|
+
code;
|
|
28
|
+
constructor(code, message) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "WireIdentityError";
|
|
31
|
+
this.code = code;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
/** Build the fixed provider identity plus the one required DSH carrier. */
|
|
35
|
+
function buildWireIdentityHeaders() {
|
|
36
|
+
const attribution = readAttributionValue();
|
|
37
|
+
const provider = {
|
|
38
|
+
"User-Agent": ANTIGRAVITY_HEADERS["User-Agent"],
|
|
39
|
+
"X-Goog-Api-Client": ANTIGRAVITY_HEADERS["X-Goog-Api-Client"],
|
|
40
|
+
"Client-Metadata": ANTIGRAVITY_HEADERS["Client-Metadata"]
|
|
41
|
+
};
|
|
42
|
+
for (const [name, value] of Object.entries(provider)) assertSafeHeaderValue(name, value, "WIRE_PROVIDER_HEADER_UNSAFE");
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
...provider,
|
|
45
|
+
[DSH_ATTRIBUTION_HEADER]: attribution
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/** Create one immutable identity policy for all private operation callers. */
|
|
49
|
+
function createWireIdentity() {
|
|
50
|
+
const headers = buildWireIdentityHeaders();
|
|
51
|
+
const headerPairs = (url, request) => {
|
|
52
|
+
assertHttpsEndpoint(url);
|
|
53
|
+
assertClosedObject(request, ["authorization", "body"], "WIRE_REQUEST_OVERRIDE");
|
|
54
|
+
if (typeof request.body !== "string" && !(request.body instanceof Uint8Array)) throw new WireIdentityError("WIRE_REQUEST_BODY_INVALID", "The private request body is not bounded bytes");
|
|
55
|
+
const authorization = validateAuthorization(request.authorization);
|
|
56
|
+
const basePairs = buildAgyCliHeaderPairs(url, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
body: request.body,
|
|
59
|
+
headers: {
|
|
60
|
+
"User-Agent": headers["User-Agent"],
|
|
61
|
+
Authorization: authorization,
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
"Accept-Encoding": "gzip"
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const result = [];
|
|
67
|
+
for (const pair of basePairs) {
|
|
68
|
+
const immutablePair = Object.freeze([pair[0], pair[1]]);
|
|
69
|
+
result.push(immutablePair);
|
|
70
|
+
if (pair[0] === "User-Agent") result.push(Object.freeze(["X-Goog-Api-Client", headers["X-Goog-Api-Client"]]), Object.freeze(["Client-Metadata", headers["Client-Metadata"]]), Object.freeze([DSH_ATTRIBUTION_HEADER, headers[DSH_ATTRIBUTION_HEADER]]));
|
|
71
|
+
}
|
|
72
|
+
return Object.freeze(result);
|
|
73
|
+
};
|
|
74
|
+
const serialize = (url, request) => {
|
|
75
|
+
const parsed = new URL(url);
|
|
76
|
+
const pairs = headerPairs(url, request);
|
|
77
|
+
const body = typeof request.body === "string" ? Buffer.from(request.body) : Buffer.from(request.body);
|
|
78
|
+
const lines = pairs.map(([name, value]) => `${name}: ${value}`).join("\r\n");
|
|
79
|
+
const head = Buffer.from(`POST ${parsed.pathname}${parsed.search} HTTP/1.1\r\n${lines}\r\n\r\n`);
|
|
80
|
+
if (!pairs.some(([name]) => name === "Transfer-Encoding")) return body.byteLength === 0 ? head : Buffer.concat([head, body]);
|
|
81
|
+
if (body.byteLength === 0) return Buffer.concat([head, Buffer.from("0\r\n\r\n")]);
|
|
82
|
+
return Buffer.concat([
|
|
83
|
+
head,
|
|
84
|
+
Buffer.from(`${body.byteLength.toString(16)}\r\n`),
|
|
85
|
+
body,
|
|
86
|
+
Buffer.from("\r\n0\r\n\r\n")
|
|
87
|
+
]);
|
|
88
|
+
};
|
|
89
|
+
return Object.freeze({
|
|
90
|
+
headers: () => headers,
|
|
91
|
+
headerPairs,
|
|
92
|
+
serialize
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/** Validate one complete, provider-fixed Wire Identity header set. */
|
|
96
|
+
function assertWireIdentityInvariant(value) {
|
|
97
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new WireIdentityError("WIRE_IDENTITY_INVARIANT", "Wire identity headers must be an object");
|
|
98
|
+
const headers = value;
|
|
99
|
+
const expected = [
|
|
100
|
+
"Client-Metadata",
|
|
101
|
+
"User-Agent",
|
|
102
|
+
"X-Goog-Api-Client",
|
|
103
|
+
DSH_ATTRIBUTION_HEADER
|
|
104
|
+
].sort();
|
|
105
|
+
const keys = Object.keys(headers).sort();
|
|
106
|
+
if (keys.length !== expected.length || keys.some((key, index) => key !== expected[index])) throw new WireIdentityError("WIRE_IDENTITY_INVARIANT", "Wire identity headers contain an unexpected field");
|
|
107
|
+
if (headers["User-Agent"] !== ANTIGRAVITY_HEADERS["User-Agent"] || headers["X-Goog-Api-Client"] !== ANTIGRAVITY_HEADERS["X-Goog-Api-Client"] || headers["Client-Metadata"] !== ANTIGRAVITY_HEADERS["Client-Metadata"]) throw new WireIdentityError("WIRE_IDENTITY_INVARIANT", "Wire identity provider headers changed");
|
|
108
|
+
if (headers["X-DeepSeek-Harness-Attribution"] === ANTIGRAVITY_HEADERS["User-Agent"]) throw new WireIdentityError("WIRE_IDENTITY_INVARIANT", "Wire identity attribution was replaced by the provider");
|
|
109
|
+
for (const key of expected) {
|
|
110
|
+
const header = headers[key];
|
|
111
|
+
if (typeof header !== "string") throw new WireIdentityError("WIRE_IDENTITY_INVARIANT", "Wire identity contains a non-text field");
|
|
112
|
+
assertSafeHeaderValue(key, header, "WIRE_IDENTITY_INVARIANT");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function readAttributionValue() {
|
|
116
|
+
let value;
|
|
117
|
+
try {
|
|
118
|
+
value = attributionHeaders();
|
|
119
|
+
} catch {
|
|
120
|
+
throw new WireIdentityError("WIRE_ATTRIBUTION_UNAVAILABLE", "DSH attribution could not be constructed");
|
|
121
|
+
}
|
|
122
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new WireIdentityError("WIRE_ATTRIBUTION_INVALID", "DSH attribution returned an invalid header set");
|
|
123
|
+
const keys = Object.keys(value);
|
|
124
|
+
if (keys.length === 0) throw new WireIdentityError("WIRE_ATTRIBUTION_MISSING", "DSH attribution did not contain a User-Agent");
|
|
125
|
+
for (const key of keys) if (!ATTRIBUTION_KEYS.has(key)) throw new WireIdentityError("WIRE_ATTRIBUTION_UNEXPECTED", "DSH attribution contained an unapproved header");
|
|
126
|
+
const lower = value["user-agent"];
|
|
127
|
+
const title = value["User-Agent"];
|
|
128
|
+
if (lower !== void 0 && title !== void 0) throw new WireIdentityError("WIRE_ATTRIBUTION_DUPLICATE", "DSH attribution contained duplicate User-Agent fields");
|
|
129
|
+
const attribution = lower ?? title;
|
|
130
|
+
if (attribution === void 0) throw new WireIdentityError("WIRE_ATTRIBUTION_MISSING", "DSH attribution did not contain a User-Agent");
|
|
131
|
+
if (attribution === ANTIGRAVITY_HEADERS["User-Agent"]) throw new WireIdentityError("WIRE_ATTRIBUTION_PROVIDER_OVERRIDE", "DSH attribution was replaced by the Antigravity provider identity");
|
|
132
|
+
assertSafeHeaderValue(DSH_ATTRIBUTION_HEADER, attribution, "WIRE_ATTRIBUTION_UNSAFE");
|
|
133
|
+
return attribution;
|
|
134
|
+
}
|
|
135
|
+
function validateAuthorization(value) {
|
|
136
|
+
if (typeof value !== "string" || !/^Bearer\s+\S+$/u.test(value)) throw new WireIdentityError("WIRE_REQUEST_UNSAFE_AUTHORIZATION", "The private request authorization value is invalid");
|
|
137
|
+
assertSafeHeaderValue("Authorization", value, "WIRE_REQUEST_UNSAFE_AUTHORIZATION");
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
function assertSafeHeaderValue(name, value, code) {
|
|
141
|
+
if (typeof value !== "string" || value.length === 0 || value.length > MAX_HEADER_VALUE_LENGTH) throw new WireIdentityError(code, `${name} is outside the safe header-value bounds`);
|
|
142
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
143
|
+
const codePoint = value.charCodeAt(index);
|
|
144
|
+
if (codePoint < 32 || codePoint === 127) throw new WireIdentityError(code, `${name} contains an unsafe header character`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function assertHttpsEndpoint(url) {
|
|
148
|
+
let parsed;
|
|
149
|
+
try {
|
|
150
|
+
parsed = new URL(url);
|
|
151
|
+
} catch {
|
|
152
|
+
throw new WireIdentityError("WIRE_REQUEST_ENDPOINT_INVALID", "The private request endpoint is invalid");
|
|
153
|
+
}
|
|
154
|
+
if (parsed.protocol !== "https:" || !ANTIGRAVITY_WIRE_ORIGINS.some((origin) => origin === parsed.origin) || !ANTIGRAVITY_WIRE_PATHS.some((path) => path === parsed.pathname) || parsed.search.length > 0 && parsed.search !== "?alt=sse" || parsed.hash.length > 0) throw new WireIdentityError("WIRE_REQUEST_ENDPOINT_INVALID", "The private request endpoint is not allowlisted");
|
|
155
|
+
}
|
|
156
|
+
function assertClosedObject(value, allowedKeys, code) {
|
|
157
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new WireIdentityError(code, "The wire identity input must be a closed object");
|
|
158
|
+
const allowed = new Set(allowedKeys);
|
|
159
|
+
for (const key of Object.keys(value)) if (!allowed.has(key)) throw new WireIdentityError(code, "The wire identity input contains an unapproved override");
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { AGY_PROVIDER_USER_AGENT, ANTIGRAVITY_WIRE_ORIGIN, ANTIGRAVITY_WIRE_ORIGINS, ANTIGRAVITY_WIRE_PATHS, DSH_ATTRIBUTION_HEADER, WireIdentityError, assertWireIdentityInvariant, buildWireIdentityHeaders, createWireIdentity };
|