chore: switch to oxfmt, oxlint - add ci checks (#3977)
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
*/**.js
|
||||
*/**.d.ts
|
||||
packages/*/dist
|
||||
packages/*/lib
|
||||
+1
-1
@@ -9,4 +9,4 @@
|
||||
- any: ["**/*.md"]
|
||||
|
||||
"📌 area: ci":
|
||||
- any: [".github/**/*"]
|
||||
- any: [".github/**/*"]
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
name: "🎨 Format & Lint"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
code-quality:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Checkout repo
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: ⎔ Setup pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
with:
|
||||
version: 10.33.2
|
||||
|
||||
- name: ⎔ Setup node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version: 20.20.2
|
||||
cache: "pnpm"
|
||||
|
||||
- name: 📥 Download deps
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: 💅 Check formatting
|
||||
run: pnpm exec oxfmt --check .
|
||||
|
||||
- name: 🔎 Lint
|
||||
run: pnpm exec oxlint .
|
||||
@@ -2,7 +2,7 @@ name: Dependabot Critical Alerts
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 8 * * *" # Daily 08:00 UTC
|
||||
- cron: "0 8 * * *" # Daily 08:00 UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
severity:
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Dependabot Weekly Summary
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 8 * * 1" # Mon 08:00 UTC
|
||||
- cron: "0 8 * * 1" # Mon 08:00 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
# Single-purpose monitoring workflow; serialise on workflow name only - we never
|
||||
@@ -12,9 +12,9 @@ concurrency:
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read # gh CLI baseline
|
||||
pull-requests: read # gh pr list (open dependabot PRs)
|
||||
actions: read # gh run list / view (parse latest dependabot run logs)
|
||||
contents: read # gh CLI baseline
|
||||
pull-requests: read # gh pr list (open dependabot PRs)
|
||||
actions: read # gh run list / view (parse latest dependabot run logs)
|
||||
|
||||
jobs:
|
||||
summary:
|
||||
|
||||
@@ -102,6 +102,11 @@ jobs:
|
||||
- 'pnpm-workspace.yaml'
|
||||
- 'turbo.json'
|
||||
|
||||
code-quality:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.code == 'true'
|
||||
uses: ./.github/workflows/code-quality.yml
|
||||
|
||||
typecheck:
|
||||
needs: changes
|
||||
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.typecheck_self == 'true'
|
||||
@@ -155,6 +160,7 @@ jobs:
|
||||
name: All PR Checks
|
||||
needs:
|
||||
- changes
|
||||
- code-quality
|
||||
- typecheck
|
||||
- webapp
|
||||
- e2e-webapp
|
||||
|
||||
@@ -3,17 +3,17 @@ name: 🧭 Helm Chart Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'helm-v*'
|
||||
- "helm-v*"
|
||||
workflow_call:
|
||||
inputs:
|
||||
chart_version:
|
||||
description: 'Chart version to release'
|
||||
description: "Chart version to release"
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
chart_version:
|
||||
description: 'Chart version to release'
|
||||
description: "Chart version to release"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
- name: Validate manifests
|
||||
uses: docker://ghcr.io/yannh/kubeconform:v0.7.0@sha256:85dbef6b4b312b99133decc9c6fc9495e9fc5f92293d4ff3b7e1b30f5611823c
|
||||
with:
|
||||
entrypoint: '/kubeconform'
|
||||
entrypoint: "/kubeconform"
|
||||
args: "-summary -output json ./helm-output"
|
||||
|
||||
release:
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
run: |
|
||||
VERSION="${STEPS_VERSION_OUTPUTS_VERSION}"
|
||||
CHART_PACKAGE="/tmp/${{ env.CHART_NAME }}-${VERSION}.tgz"
|
||||
|
||||
|
||||
# Push to GHCR OCI registry
|
||||
helm push "$CHART_PACKAGE" "oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts"
|
||||
env:
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
oci://${{ env.REGISTRY }}/${{ github.repository_owner }}/charts/${{ env.CHART_NAME }} \
|
||||
--version "${{ steps.version.outputs.version }}"
|
||||
```
|
||||
|
||||
|
||||
### Changes
|
||||
See commit history for detailed changes in this release.
|
||||
files: |
|
||||
|
||||
@@ -4,14 +4,14 @@ on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- '.github/actions/**'
|
||||
- '.github/zizmor.yml'
|
||||
- ".github/workflows/**"
|
||||
- ".github/actions/**"
|
||||
- ".github/zizmor.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- '.github/actions/**'
|
||||
- '.github/zizmor.yml'
|
||||
- ".github/workflows/**"
|
||||
- ".github/actions/**"
|
||||
- ".github/zizmor.yml"
|
||||
|
||||
permissions: {}
|
||||
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@ rules:
|
||||
unpinned-uses:
|
||||
config:
|
||||
policies:
|
||||
'*': hash-pin
|
||||
"*": hash-pin
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"jsxSingleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": false,
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"sortPackageJson": false,
|
||||
"ignorePatterns": [
|
||||
"node_modules",
|
||||
"apps/webapp",
|
||||
".env",
|
||||
".env.local",
|
||||
"pnpm-lock.yaml",
|
||||
"tailwind.css",
|
||||
".babelrc.json",
|
||||
"**/.react-email/",
|
||||
"**/storybook-static/",
|
||||
"**/.changeset/",
|
||||
"**/dist/",
|
||||
"internal-packages/tsql/src/grammar/",
|
||||
// Maybe turn these on in the future
|
||||
"**/*.yaml",
|
||||
"**/*.mdx",
|
||||
"**/*.md"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["typescript", "import", "react"],
|
||||
"ignorePatterns": [
|
||||
"**/dist/**",
|
||||
"**/build/**",
|
||||
"**/*.d.ts",
|
||||
"**/seed.js",
|
||||
"**/seedCloud.ts",
|
||||
"**/populate.js",
|
||||
"apps/webapp/**"
|
||||
],
|
||||
// All rules below are disabled because they currently fire on the existing
|
||||
// codebase (1748 warnings across these 20 rules as of this commit). Disabled
|
||||
// to keep the lint baseline green; re-enable and fix incrementally.
|
||||
"rules": {
|
||||
// eslint
|
||||
"no-unused-vars": "off",
|
||||
"no-unused-expressions": "off",
|
||||
"no-control-regex": "off",
|
||||
"no-empty-pattern": "off",
|
||||
"no-unused-private-class-members": "off",
|
||||
"no-useless-catch": "off",
|
||||
"no-unsafe-optional-chaining": "off",
|
||||
"no-unreachable": "off",
|
||||
"require-yield": "off",
|
||||
"no-async-promise-executor": "off",
|
||||
"no-unsafe-finally": "off",
|
||||
"no-useless-escape": "off",
|
||||
// typescript
|
||||
"typescript/consistent-type-imports": "off",
|
||||
"typescript/no-this-alias": "off",
|
||||
"typescript/no-non-null-asserted-optional-chain": "off",
|
||||
"typescript/no-unnecessary-parameter-property-assignment": "off",
|
||||
// import
|
||||
"import/no-duplicates": "off",
|
||||
"import/namespace": "off",
|
||||
// react
|
||||
"react/jsx-key": "off",
|
||||
"react/no-children-prop": "off",
|
||||
// react-hooks
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
// oxlint treats any use*()/use() call as a React hook, producing false
|
||||
// positives in async/test code (testcontainers, cli-v3 e2e).
|
||||
"react-hooks/rules-of-hooks": "off"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
node_modules
|
||||
.env
|
||||
.env.local
|
||||
pnpm-lock.yaml
|
||||
tailwind.css
|
||||
.babelrc.json
|
||||
**/.react-email/
|
||||
**/storybook-static/
|
||||
**/.changeset/
|
||||
**/dist/
|
||||
@@ -27,4 +27,4 @@
|
||||
"esbuild": "^0.19.11",
|
||||
"tsx": "^4.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
"esbuild": "^0.19.11",
|
||||
"tsx": "^4.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
"esbuild": "^0.19.11",
|
||||
"tsx": "^4.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@ describe("K8sPodCountSignalSource", () => {
|
||||
engageThreshold: 10000,
|
||||
releaseThreshold: 5000,
|
||||
});
|
||||
expect((await source.read()).engaged).toBe(true); // engage
|
||||
expect((await source.read()).engaged).toBe(true); // engage
|
||||
count = 7000;
|
||||
expect((await source.read()).engaged).toBe(true); // band -> still engaged
|
||||
expect((await source.read()).engaged).toBe(true); // band -> still engaged
|
||||
count = 4999;
|
||||
expect((await source.read()).engaged).toBe(false); // below release -> off
|
||||
count = 7000;
|
||||
|
||||
@@ -49,14 +49,17 @@ describe("RedisBackpressureSignalSource", () => {
|
||||
}
|
||||
});
|
||||
|
||||
redisTest("returns null for valid JSON of the wrong shape (fail-open)", async ({ redisOptions }) => {
|
||||
const redis = new Redis(redisOptions);
|
||||
try {
|
||||
await redis.set(KEY, JSON.stringify({ foo: "bar" }));
|
||||
const source = new RedisBackpressureSignalSource(redis, KEY);
|
||||
expect(await source.read()).toBeNull();
|
||||
} finally {
|
||||
await redis.quit();
|
||||
redisTest(
|
||||
"returns null for valid JSON of the wrong shape (fail-open)",
|
||||
async ({ redisOptions }) => {
|
||||
const redis = new Redis(redisOptions);
|
||||
try {
|
||||
await redis.set(KEY, JSON.stringify({ foo: "bar" }));
|
||||
const source = new RedisBackpressureSignalSource(redis, KEY);
|
||||
expect(await source.read()).toBeNull();
|
||||
} finally {
|
||||
await redis.quit();
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
|
||||
@@ -75,9 +75,21 @@ export const Env = z
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_TLS_DISABLED: BoolEnv.default(false),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENABLED: BoolEnv.default(false),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_DRY_RUN: BoolEnv.default(true),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENGAGE: z.coerce.number().int().positive().default(10_000),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_RELEASE: z.coerce.number().int().positive().default(5_000),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_REFRESH_MS: z.coerce.number().int().positive().default(5_000),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_ENGAGE: z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.default(10_000),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_RELEASE: z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.default(5_000),
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_REFRESH_MS: z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.default(5_000),
|
||||
// Hard timeout on the apiserver /metrics scrape. A hung request would otherwise
|
||||
// never settle and freeze the monitor's refresh loop (fail-open silently).
|
||||
TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_SCRAPE_TIMEOUT_MS: z.coerce
|
||||
@@ -350,7 +362,10 @@ export const Env = z
|
||||
path: ["TRIGGER_WORKLOAD_API_DOMAIN"],
|
||||
});
|
||||
}
|
||||
if (data.TRIGGER_DEQUEUE_BACKPRESSURE_ENABLED && !data.TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_HOST) {
|
||||
if (
|
||||
data.TRIGGER_DEQUEUE_BACKPRESSURE_ENABLED &&
|
||||
!data.TRIGGER_DEQUEUE_BACKPRESSURE_REDIS_HOST
|
||||
) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message:
|
||||
|
||||
@@ -274,7 +274,10 @@ class ManagedSupervisor {
|
||||
rampMs: env.TRIGGER_DEQUEUE_BACKPRESSURE_RAMP_MS,
|
||||
dryRun: env.TRIGGER_DEQUEUE_BACKPRESSURE_POD_COUNT_DRY_RUN,
|
||||
logger: this.logger,
|
||||
metrics: new BackpressureMetrics({ register, prefix: "supervisor_backpressure_pod_count" }),
|
||||
metrics: new BackpressureMetrics({
|
||||
register,
|
||||
prefix: "supervisor_backpressure_pod_count",
|
||||
}),
|
||||
})
|
||||
);
|
||||
this.logger.log("🛑 Dequeue backpressure enabled (pod-count source)", {
|
||||
|
||||
@@ -10,7 +10,9 @@ const DELAY_MS = 200;
|
||||
const SETTLE_MS = 600;
|
||||
|
||||
function createService() {
|
||||
const snapshot = vi.fn(async (_opts: { runnerId: string; metadata: Record<string, string> }) => true);
|
||||
const snapshot = vi.fn(
|
||||
async (_opts: { runnerId: string; metadata: Record<string, string> }) => true
|
||||
);
|
||||
|
||||
const computeManager = {
|
||||
snapshotDelayMs: DELAY_MS,
|
||||
@@ -97,9 +99,7 @@ describe("ComputeSnapshotService", () => {
|
||||
expect(service.cancel("run_1", "runner-b")).toBe(false);
|
||||
|
||||
await vi.waitFor(() => expect(snapshot).toHaveBeenCalledTimes(1), { timeout: 2_000 });
|
||||
expect(snapshot).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ runnerId: "runner-a" })
|
||||
);
|
||||
expect(snapshot).toHaveBeenCalledWith(expect.objectContaining({ runnerId: "runner-a" }));
|
||||
} finally {
|
||||
service.stop();
|
||||
}
|
||||
|
||||
@@ -31,9 +31,7 @@ describe("buildPayload", () => {
|
||||
expect(triggerAttr).toEqual({ key: "$trigger", value: { boolValue: true } });
|
||||
|
||||
// Resource attributes
|
||||
const envAttr = resourceSpan.resource.attributes.find(
|
||||
(a) => a.key === "ctx.environment.id"
|
||||
);
|
||||
const envAttr = resourceSpan.resource.attributes.find((a) => a.key === "ctx.environment.id");
|
||||
expect(envAttr).toEqual({
|
||||
key: "ctx.environment.id",
|
||||
value: { stringValue: "env_123" },
|
||||
|
||||
@@ -19,10 +19,7 @@ function makeMessage(runFriendlyId = "run_1"): DequeuedMessage {
|
||||
} as unknown as DequeuedMessage;
|
||||
}
|
||||
|
||||
function createService(opts: {
|
||||
latestSnapshotId?: string;
|
||||
probeError?: boolean;
|
||||
}) {
|
||||
function createService(opts: { latestSnapshotId?: string; probeError?: boolean }) {
|
||||
const getLatestSnapshot = vi.fn(async (_runId: string) =>
|
||||
opts.probeError
|
||||
? { success: false as const, error: "connection refused" }
|
||||
|
||||
@@ -11,12 +11,7 @@ export { type Env, isValidRequestId, newState, type NewStateOptions } from "./ne
|
||||
export { emit, EmitMessage } from "./emit.js";
|
||||
export { parseTraceId } from "./traceparent.js";
|
||||
export { fromContext, wideEventStorage } from "./context.js";
|
||||
export {
|
||||
type PhaseOpt,
|
||||
recordPhase,
|
||||
recordPhaseSince,
|
||||
timePhase,
|
||||
} from "./record.js";
|
||||
export { type PhaseOpt, recordPhase, recordPhaseSince, timePhase } from "./record.js";
|
||||
export {
|
||||
emitOneShot,
|
||||
runWideEvent,
|
||||
|
||||
@@ -124,7 +124,8 @@ describe("runWideEvent", () => {
|
||||
{
|
||||
service: "supervisor",
|
||||
env: {},
|
||||
enabled: true, op: "test",
|
||||
enabled: true,
|
||||
op: "test",
|
||||
setup: (state) => {
|
||||
state.meta.run_id = "run_abc";
|
||||
state.extras.iteration = "dequeue";
|
||||
@@ -158,16 +159,13 @@ describe("runWideEvent", () => {
|
||||
const lines = await captureStdout(async () => {
|
||||
await Promise.all(
|
||||
["a", "b", "c"].map((tag) =>
|
||||
runWideEvent(
|
||||
{ service: "supervisor", env: {}, enabled: true, op: "test" },
|
||||
async () => {
|
||||
const s = fromContext();
|
||||
if (!s) throw new Error("no state");
|
||||
s.meta.tag = tag;
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
expect(s.meta.tag).toBe(tag);
|
||||
}
|
||||
)
|
||||
runWideEvent({ service: "supervisor", env: {}, enabled: true, op: "test" }, async () => {
|
||||
const s = fromContext();
|
||||
if (!s) throw new Error("no state");
|
||||
s.meta.tag = tag;
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
expect(s.meta.tag).toBe(tag);
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
@@ -182,7 +180,8 @@ describe("emitOneShot", () => {
|
||||
emitOneShot({
|
||||
service: "supervisor",
|
||||
env: {},
|
||||
enabled: true, op: "test",
|
||||
enabled: true,
|
||||
op: "test",
|
||||
populate: (s) => {
|
||||
s.meta.run_id = "run_abc";
|
||||
s.extras.event = "run:start";
|
||||
|
||||
@@ -15,9 +15,7 @@ describe("runnerNameForAttempt", () => {
|
||||
|
||||
describe("isRetryableCreateError", () => {
|
||||
it("retries statuses where the create definitely did not commit", () => {
|
||||
expect(isRetryableCreateError(new ComputeClientError(500, "tap busy", "http://gw"))).toBe(
|
||||
true
|
||||
);
|
||||
expect(isRetryableCreateError(new ComputeClientError(500, "tap busy", "http://gw"))).toBe(true);
|
||||
expect(isRetryableCreateError(new ComputeClientError(503, "no placement", "http://gw"))).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
@@ -250,9 +250,7 @@ export class ComputeWorkloadManager implements WorkloadManager {
|
||||
// name registered, so subsequent attempts use a suffixed name.
|
||||
let suffixAttempts = false;
|
||||
for (; attempt <= this.createMaxAttempts; attempt++) {
|
||||
const attemptRunnerId = suffixAttempts
|
||||
? runnerNameForAttempt(runnerId, attempt)
|
||||
: runnerId;
|
||||
const attemptRunnerId = suffixAttempts ? runnerNameForAttempt(runnerId, attempt) : runnerId;
|
||||
[error, data] = await tryCatch(
|
||||
this.compute.instances.create(
|
||||
attemptRunnerId === runnerId
|
||||
|
||||
@@ -431,7 +431,8 @@ export class KubernetesWorkloadManager implements WorkloadManager {
|
||||
// Only large machine affinity produces hard requirements (non-large runs must stay off the large pool).
|
||||
// Schedule affinity is soft both ways.
|
||||
const required = [
|
||||
...(largeNodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms ?? []),
|
||||
...(largeNodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution?.nodeSelectorTerms ??
|
||||
[]),
|
||||
];
|
||||
|
||||
const hasNodeAffinity = preferred.length > 0 || required.length > 0;
|
||||
@@ -443,7 +444,9 @@ export class KubernetesWorkloadManager implements WorkloadManager {
|
||||
return {
|
||||
...(hasNodeAffinity && {
|
||||
nodeAffinity: {
|
||||
...(preferred.length > 0 && { preferredDuringSchedulingIgnoredDuringExecution: preferred }),
|
||||
...(preferred.length > 0 && {
|
||||
preferredDuringSchedulingIgnoredDuringExecution: preferred,
|
||||
}),
|
||||
...(required.length > 0 && {
|
||||
requiredDuringSchedulingIgnoredDuringExecution: { nodeSelectorTerms: required },
|
||||
}),
|
||||
@@ -497,7 +500,10 @@ export class KubernetesWorkloadManager implements WorkloadManager {
|
||||
}
|
||||
|
||||
#getScheduleNodeAffinityRules(isScheduledRun: boolean): k8s.V1NodeAffinity | undefined {
|
||||
if (!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_ENABLED || !env.KUBERNETES_SCHEDULED_RUN_AFFINITY_POOL_LABEL_VALUE) {
|
||||
if (
|
||||
!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_ENABLED ||
|
||||
!env.KUBERNETES_SCHEDULED_RUN_AFFINITY_POOL_LABEL_VALUE
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import type { EnvironmentType, MachinePreset, PlacementTag, RunAnnotations } from "@trigger.dev/core/v3";
|
||||
import type {
|
||||
EnvironmentType,
|
||||
MachinePreset,
|
||||
PlacementTag,
|
||||
RunAnnotations,
|
||||
} from "@trigger.dev/core/v3";
|
||||
|
||||
export interface WorkloadManagerOptions {
|
||||
workloadApiProtocol: "http" | "https";
|
||||
|
||||
@@ -317,9 +317,7 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
return;
|
||||
}
|
||||
|
||||
reply.json(
|
||||
completeResponse.data satisfies WorkloadRunAttemptCompleteResponseBody
|
||||
);
|
||||
reply.json(completeResponse.data satisfies WorkloadRunAttemptCompleteResponseBody);
|
||||
return;
|
||||
}
|
||||
),
|
||||
@@ -566,7 +564,9 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
}
|
||||
|
||||
reply.json(
|
||||
dequeueResponse.data.map(legacifyCheckpointType) satisfies WorkloadDequeueFromVersionResponseBody
|
||||
dequeueResponse.data.map(
|
||||
legacifyCheckpointType
|
||||
) satisfies WorkloadDequeueFromVersionResponseBody
|
||||
);
|
||||
}
|
||||
),
|
||||
@@ -613,16 +613,22 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
|
||||
httpServer.route("/api/v1/compute/snapshot-complete", "POST", {
|
||||
bodySchema: SnapshotCallbackPayloadSchema,
|
||||
handler: async (ctx) =>
|
||||
this.wideRoute(ctx, "snapshot.callback", "/api/v1/compute/snapshot-complete", "POST", async () => {
|
||||
const { reply, body } = ctx;
|
||||
if (!this.snapshotService) {
|
||||
reply.empty(404);
|
||||
return;
|
||||
}
|
||||
this.wideRoute(
|
||||
ctx,
|
||||
"snapshot.callback",
|
||||
"/api/v1/compute/snapshot-complete",
|
||||
"POST",
|
||||
async () => {
|
||||
const { reply, body } = ctx;
|
||||
if (!this.snapshotService) {
|
||||
reply.empty(404);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await this.snapshotService.handleCallback(body);
|
||||
reply.empty(result.status);
|
||||
}),
|
||||
const result = await this.snapshotService.handleCallback(body);
|
||||
reply.empty(result.status);
|
||||
}
|
||||
),
|
||||
});
|
||||
|
||||
return httpServer;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"plugins": ["react-hooks", "@typescript-eslint/eslint-plugin", "import"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {
|
||||
// Autofixes imports from "@trigger.dev/core" to fine grained modules
|
||||
// "@trigger.dev/no-trigger-core-import": "error",
|
||||
// Normalize `import type {}` and `import { type }`
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"warn",
|
||||
{
|
||||
// the "type" annotation can get tangled and cause syntax errors
|
||||
// during some autofixes, so easier to just turn it off
|
||||
"prefer": "type-imports",
|
||||
"disallowTypeAnnotations": true,
|
||||
"fixStyle": "inline-type-imports"
|
||||
}
|
||||
],
|
||||
// no-trigger-core-import splits imports into multiple lines
|
||||
// this one merges them back into a single line
|
||||
// if they still import from the same module
|
||||
"import/no-duplicates": ["warn", { "prefer-inline": true }],
|
||||
// lots of undeclared vars, enable this rule if you want to clean them up
|
||||
"turbo/no-undeclared-env-vars": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ignorePatterns": ["seed.js", "seedCloud.ts", "populate.js"]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
node_modules
|
||||
|
||||
/build
|
||||
/public/build
|
||||
.env
|
||||
|
||||
/cypress/screenshots
|
||||
/cypress/videos
|
||||
/postgres-data
|
||||
|
||||
/app/styles/tailwind.css
|
||||
@@ -10,8 +10,8 @@
|
||||
"build:sentry": "esbuild --platform=node --format=cjs --outbase=. ./sentry.server.ts ./app/utils/sentryTraceContext.server.ts --outdir=build --sourcemap",
|
||||
"dev": "cross-env PORT=3030 remix dev -c \"node ./build/server.js\"",
|
||||
"dev:worker": "cross-env NODE_PATH=../../node_modules/.pnpm/node_modules node ./build/server.js",
|
||||
"format": "prettier --write .",
|
||||
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
|
||||
"format": "oxfmt .",
|
||||
"lint": "oxlint -c ../../.oxlintrc.json",
|
||||
"start": "cross-env NODE_ENV=production node --max-old-space-size=8192 ./build/server.js",
|
||||
"start:local": "cross-env node --max-old-space-size=8192 ./build/server.js",
|
||||
"typecheck": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" tsc --noEmit -p ./tsconfig.check.json",
|
||||
@@ -21,11 +21,6 @@
|
||||
"test": "vitest --no-file-parallelism",
|
||||
"eval:dev": "evalite watch"
|
||||
},
|
||||
"eslintIgnore": [
|
||||
"/node_modules",
|
||||
"/build",
|
||||
"/public/build"
|
||||
],
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^3.0.0",
|
||||
"@ai-sdk/openai": "^3.0.0",
|
||||
@@ -248,7 +243,6 @@
|
||||
"@internal/replication": "workspace:*",
|
||||
"@internal/testcontainers": "workspace:*",
|
||||
"@remix-run/dev": "2.17.4",
|
||||
"@remix-run/eslint-config": "2.17.4",
|
||||
"@remix-run/testing": "^2.17.4",
|
||||
"@sentry/cli": "2.50.2",
|
||||
"@swc/core": "^1.3.4",
|
||||
@@ -259,7 +253,6 @@
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/cookie": "^0.6.0",
|
||||
"@types/eslint": "^8.4.6",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/humanize-duration": "^3.27.1",
|
||||
"@types/json-query": "^2.2.3",
|
||||
@@ -280,25 +273,16 @@
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@types/tar": "^6.1.4",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.6",
|
||||
"@typescript-eslint/parser": "^5.59.6",
|
||||
"autoevals": "^0.0.130",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"css-loader": "^6.10.0",
|
||||
"datepicker": "link:@types/@react-aria/datepicker",
|
||||
"engine.io": "^6.5.4",
|
||||
"esbuild": "^0.15.10",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"eslint-plugin-turbo": "^2.0.4",
|
||||
"evalite": "1.0.0-beta.16",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-import": "^16.0.1",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"rimraf": "^6.0.1",
|
||||
"style-loader": "^3.3.4",
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
module.exports = {
|
||||
...require("../../prettier.config.js"),
|
||||
plugins: [require("prettier-plugin-tailwindcss")],
|
||||
};
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"id": "g2k5ln95n6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -238,7 +243,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -298,7 +308,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
|
||||
"id": 9,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -355,7 +370,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
|
||||
"id": 10,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -420,7 +440,12 @@
|
||||
"gridPos": { "h": 8, "w": 8, "x": 0, "y": 25 },
|
||||
"id": 12,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -467,7 +492,12 @@
|
||||
"gridPos": { "h": 8, "w": 8, "x": 8, "y": 25 },
|
||||
"id": 13,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -561,7 +591,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 34 },
|
||||
"id": 16,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -618,7 +653,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 34 },
|
||||
"id": 17,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -683,7 +723,12 @@
|
||||
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 43 },
|
||||
"id": 19,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
|
||||
@@ -14,4 +14,3 @@ providers:
|
||||
allowUiUpdates: true
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards
|
||||
|
||||
|
||||
@@ -142,9 +142,7 @@
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{ "color": "green", "value": null }
|
||||
]
|
||||
"steps": [{ "color": "green", "value": null }]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
@@ -207,7 +205,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -254,7 +257,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -324,7 +332,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
|
||||
"id": 9,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -371,7 +384,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
|
||||
"id": 10,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -418,7 +436,12 @@
|
||||
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 24 },
|
||||
"id": 11,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "right", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -443,4 +466,3 @@
|
||||
"uid": "nodejs-runtime",
|
||||
"version": 1
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
{
|
||||
"title": "Realtime Native Backend",
|
||||
"uid": "realtime-native",
|
||||
"tags": [
|
||||
"trigger.dev",
|
||||
"realtime"
|
||||
],
|
||||
"tags": ["trigger.dev", "realtime"],
|
||||
"timezone": "browser",
|
||||
"schemaVersion": 39,
|
||||
"refresh": "10s",
|
||||
@@ -174,9 +171,7 @@
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
]
|
||||
"calcs": ["lastNotNull"]
|
||||
}
|
||||
},
|
||||
"description": "A backstop that finds missed changes means the notify/replay path is leaking. Alert on sustained non-zero."
|
||||
@@ -500,4 +495,4 @@
|
||||
"description": "hit/coalesced vs miss = the single-flight cache collapsing same-filter herds. Gate in use near the limit = reconnect stampedes queueing."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 7 },
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -233,7 +238,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 7 },
|
||||
"id": 7,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -293,7 +303,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
|
||||
"id": 9,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -350,7 +365,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
|
||||
"id": 10,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -415,7 +435,12 @@
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 25 },
|
||||
"id": 13,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
@@ -519,7 +544,12 @@
|
||||
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 34 },
|
||||
"id": 16,
|
||||
"options": {
|
||||
"legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
|
||||
"legend": {
|
||||
"calcs": ["mean", "max"],
|
||||
"displayMode": "table",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": { "mode": "multi", "sort": "desc" }
|
||||
},
|
||||
"targets": [
|
||||
|
||||
@@ -15,4 +15,3 @@ datasources:
|
||||
httpMethod: POST
|
||||
manageAlerts: true
|
||||
prometheusType: Prometheus
|
||||
|
||||
|
||||
@@ -30,4 +30,3 @@ scrape_configs:
|
||||
- job_name: "prometheus"
|
||||
static_configs:
|
||||
- targets: ["localhost:9090"]
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
"upstream": "host.docker.internal:3030",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
+13
-60
@@ -10,11 +10,7 @@
|
||||
},
|
||||
"favicon": "/images/favicon.png",
|
||||
"contextual": {
|
||||
"options": [
|
||||
"copy",
|
||||
"view",
|
||||
"claude"
|
||||
]
|
||||
"options": ["copy", "view", "claude"]
|
||||
},
|
||||
"navigation": {
|
||||
"dropdowns": [
|
||||
@@ -40,11 +36,7 @@
|
||||
"pages": [
|
||||
{
|
||||
"group": "Tasks",
|
||||
"pages": [
|
||||
"tasks/overview",
|
||||
"tasks/schemaTask",
|
||||
"tasks/scheduled"
|
||||
]
|
||||
"pages": ["tasks/overview", "tasks/schemaTask", "tasks/scheduled"]
|
||||
},
|
||||
"triggering",
|
||||
"runs",
|
||||
@@ -57,10 +49,7 @@
|
||||
"building-with-ai",
|
||||
{
|
||||
"group": "MCP Server",
|
||||
"pages": [
|
||||
"mcp-introduction",
|
||||
"mcp-tools"
|
||||
]
|
||||
"pages": ["mcp-introduction", "mcp-tools"]
|
||||
},
|
||||
"skills",
|
||||
"mcp-agent-rules"
|
||||
@@ -74,12 +63,7 @@
|
||||
"errors-retrying",
|
||||
{
|
||||
"group": "Wait",
|
||||
"pages": [
|
||||
"wait",
|
||||
"wait-for",
|
||||
"wait-until",
|
||||
"wait-for-token"
|
||||
]
|
||||
"pages": ["wait", "wait-for", "wait-until", "wait-for-token"]
|
||||
},
|
||||
"queue-concurrency",
|
||||
"versioning",
|
||||
@@ -203,10 +187,7 @@
|
||||
"deployment/atomic-deployment",
|
||||
{
|
||||
"group": "Deployment integrations",
|
||||
"pages": [
|
||||
"github-integration",
|
||||
"vercel-integration"
|
||||
]
|
||||
"pages": ["github-integration", "vercel-integration"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -270,19 +251,11 @@
|
||||
},
|
||||
{
|
||||
"group": "Observability",
|
||||
"pages": [
|
||||
"observability/query",
|
||||
"observability/dashboards"
|
||||
]
|
||||
"pages": ["observability/query", "observability/dashboards"]
|
||||
},
|
||||
{
|
||||
"group": "Using the Dashboard",
|
||||
"pages": [
|
||||
"run-tests",
|
||||
"troubleshooting-alerts",
|
||||
"replaying",
|
||||
"bulk-actions"
|
||||
]
|
||||
"pages": ["run-tests", "troubleshooting-alerts", "replaying", "bulk-actions"]
|
||||
},
|
||||
{
|
||||
"group": "Troubleshooting",
|
||||
@@ -305,30 +278,18 @@
|
||||
"self-hosting/kubernetes",
|
||||
{
|
||||
"group": "Environment variables",
|
||||
"pages": [
|
||||
"self-hosting/env/webapp",
|
||||
"self-hosting/env/supervisor"
|
||||
]
|
||||
"pages": ["self-hosting/env/webapp", "self-hosting/env/supervisor"]
|
||||
},
|
||||
"open-source-self-hosting"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Open source",
|
||||
"pages": [
|
||||
"open-source-contributing",
|
||||
"github-repo",
|
||||
"changelog",
|
||||
"roadmap"
|
||||
]
|
||||
"pages": ["open-source-contributing", "github-repo", "changelog", "roadmap"]
|
||||
},
|
||||
{
|
||||
"group": "Help",
|
||||
"pages": [
|
||||
"community",
|
||||
"help-slack",
|
||||
"help-email"
|
||||
]
|
||||
"pages": ["community", "help-slack", "help-email"]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -471,9 +432,7 @@
|
||||
"groups": [
|
||||
{
|
||||
"group": "Introduction",
|
||||
"pages": [
|
||||
"guides/introduction"
|
||||
]
|
||||
"pages": ["guides/introduction"]
|
||||
},
|
||||
{
|
||||
"group": "Frameworks",
|
||||
@@ -539,10 +498,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Migration guides",
|
||||
"pages": [
|
||||
"migration-mergent",
|
||||
"migration-n8n"
|
||||
]
|
||||
"pages": ["migration-mergent", "migration-n8n"]
|
||||
},
|
||||
{
|
||||
"group": "Use cases",
|
||||
@@ -633,10 +589,7 @@
|
||||
"href": "https://trigger.dev"
|
||||
},
|
||||
"api": {
|
||||
"openapi": [
|
||||
"openapi.yml",
|
||||
"v3-openapi.yaml"
|
||||
],
|
||||
"openapi": ["openapi.yml", "v3-openapi.yaml"],
|
||||
"playground": {
|
||||
"display": "simple"
|
||||
}
|
||||
|
||||
+26
-26
@@ -1,31 +1,31 @@
|
||||
button~.absolute.peer-hover\:opacity-100 {
|
||||
color: #000
|
||||
button ~ .absolute.peer-hover\:opacity-100 {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* Code block colors - Trigger.dark theme */
|
||||
--mint-color-background: #121317;
|
||||
--mint-color-text: #D4D4D4;
|
||||
--mint-token-constant: #9B99FF;
|
||||
--mint-token-string: #AFEC73;
|
||||
--mint-token-comment: #5F6570;
|
||||
--mint-token-keyword: #E888F8;
|
||||
--mint-token-parameter: #CCCBFF;
|
||||
--mint-token-function: #D9F07C;
|
||||
--mint-token-string-expression: #AFEC73;
|
||||
--mint-token-punctuation: #878C99;
|
||||
--mint-token-link: #826DFF;
|
||||
/* Code block colors - Trigger.dark theme */
|
||||
--mint-color-background: #121317;
|
||||
--mint-color-text: #d4d4d4;
|
||||
--mint-token-constant: #9b99ff;
|
||||
--mint-token-string: #afec73;
|
||||
--mint-token-comment: #5f6570;
|
||||
--mint-token-keyword: #e888f8;
|
||||
--mint-token-parameter: #cccbff;
|
||||
--mint-token-function: #d9f07c;
|
||||
--mint-token-string-expression: #afec73;
|
||||
--mint-token-punctuation: #878c99;
|
||||
--mint-token-link: #826dff;
|
||||
|
||||
/* Shiki css-variables fallbacks */
|
||||
--shiki-foreground: #D4D4D4;
|
||||
--shiki-background: #121317;
|
||||
--shiki-token-constant: #9B99FF;
|
||||
--shiki-token-string: #AFEC73;
|
||||
--shiki-token-comment: #5F6570;
|
||||
--shiki-token-keyword: #E888F8;
|
||||
--shiki-token-parameter: #CCCBFF;
|
||||
--shiki-token-function: #D9F07C;
|
||||
--shiki-token-string-expression: #AFEC73;
|
||||
--shiki-token-punctuation: #878C99;
|
||||
--shiki-token-link: #826DFF;
|
||||
/* Shiki css-variables fallbacks */
|
||||
--shiki-foreground: #d4d4d4;
|
||||
--shiki-background: #121317;
|
||||
--shiki-token-constant: #9b99ff;
|
||||
--shiki-token-string: #afec73;
|
||||
--shiki-token-comment: #5f6570;
|
||||
--shiki-token-keyword: #e888f8;
|
||||
--shiki-token-parameter: #cccbff;
|
||||
--shiki-token-function: #d9f07c;
|
||||
--shiki-token-string-expression: #afec73;
|
||||
--shiki-token-punctuation: #878c99;
|
||||
--shiki-token-link: #826dff;
|
||||
}
|
||||
|
||||
@@ -238,4 +238,4 @@ networks:
|
||||
supervisor:
|
||||
name: supervisor
|
||||
webapp:
|
||||
name: webapp
|
||||
name: webapp
|
||||
|
||||
@@ -45,7 +45,13 @@ services:
|
||||
DOCKER_REGISTRY_PASSWORD: ${DOCKER_REGISTRY_PASSWORD:-}
|
||||
DOCKER_AUTOREMOVE_EXITED_CONTAINERS: 0
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "http.get('http://localhost:8020/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"node",
|
||||
"-e",
|
||||
"http.get('http://localhost:8020/health', res => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))",
|
||||
]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
Vendored
+1
-1
@@ -18,4 +18,4 @@
|
||||
"test": "vitest",
|
||||
"test:watch": "vitest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -28,9 +28,10 @@ export type LRUMemoryStoreConfig = {
|
||||
* but will be evicted by LRU when the cache is full.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export class LRUMemoryStore<TNamespace extends string, TValue = any>
|
||||
implements Store<TNamespace, TValue>
|
||||
{
|
||||
export class LRUMemoryStore<TNamespace extends string, TValue = any> implements Store<
|
||||
TNamespace,
|
||||
TValue
|
||||
> {
|
||||
readonly name: string;
|
||||
private readonly cache: LRUCache<string, Entry<TValue>>;
|
||||
|
||||
@@ -110,10 +111,7 @@ export class LRUMemoryStore<TNamespace extends string, TValue = any>
|
||||
}
|
||||
}
|
||||
|
||||
async remove(
|
||||
namespace: TNamespace,
|
||||
keys: string | string[]
|
||||
): Promise<Result<void, CacheError>> {
|
||||
async remove(namespace: TNamespace, keys: string | string[]): Promise<Result<void, CacheError>> {
|
||||
try {
|
||||
const keyArray = Array.isArray(keys) ? keys : [keys];
|
||||
|
||||
|
||||
+4
-3
@@ -9,9 +9,10 @@ export type RedisCacheStoreConfig = {
|
||||
useModernCacheKeyBuilder?: boolean;
|
||||
};
|
||||
|
||||
export class RedisCacheStore<TNamespace extends string, TValue = any>
|
||||
implements Store<TNamespace, TValue>
|
||||
{
|
||||
export class RedisCacheStore<TNamespace extends string, TValue = any> implements Store<
|
||||
TNamespace,
|
||||
TValue
|
||||
> {
|
||||
public readonly name = "redis";
|
||||
private readonly redis: Redis;
|
||||
|
||||
|
||||
@@ -518,7 +518,10 @@ export class ClickhouseClient implements ClickhouseReader, ClickhouseWriter {
|
||||
};
|
||||
}
|
||||
|
||||
public queryFastStream<TOut extends Record<string, any>, TParams extends Record<string, any>>(req: {
|
||||
public queryFastStream<
|
||||
TOut extends Record<string, any>,
|
||||
TParams extends Record<string, any>,
|
||||
>(req: {
|
||||
name: string;
|
||||
query: string;
|
||||
columns: Array<string | ColumnExpression>;
|
||||
|
||||
@@ -95,7 +95,10 @@ export class NoopClient implements ClickhouseReader, ClickhouseWriter {
|
||||
};
|
||||
}
|
||||
|
||||
public queryFastStream<TOut extends Record<string, any>, TParams extends Record<string, any>>(req: {
|
||||
public queryFastStream<
|
||||
TOut extends Record<string, any>,
|
||||
TParams extends Record<string, any>,
|
||||
>(req: {
|
||||
name: string;
|
||||
query: string;
|
||||
columns: string[];
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
type QuerySettings,
|
||||
type FieldMappings,
|
||||
type TimeRange,
|
||||
type WhereClauseCondition
|
||||
type WhereClauseCondition,
|
||||
} from "@internal/tsql";
|
||||
import type { ClickhouseReader, QueryStats } from "./types.js";
|
||||
import { QueryError } from "./errors.js";
|
||||
@@ -180,9 +180,10 @@ export async function executeTSQL<TOut extends z.ZodSchema>(
|
||||
try {
|
||||
// 1. Compile the TSQL query to ClickHouse SQL
|
||||
// Pass maxRows + 1 to fetch one extra row for overflow detection
|
||||
const compiledSettings = maxRows !== undefined
|
||||
? { ...options.querySettings, maxRows: maxRows + 1 }
|
||||
: options.querySettings;
|
||||
const compiledSettings =
|
||||
maxRows !== undefined
|
||||
? { ...options.querySettings, maxRows: maxRows + 1 }
|
||||
: options.querySettings;
|
||||
|
||||
const { sql, params, columns, hiddenColumns } = compileTSQL(options.query, {
|
||||
tableSchema: options.tableSchema,
|
||||
|
||||
@@ -157,10 +157,7 @@ export function getSessionsQueryBuilder(ch: ClickhouseReader, settings?: ClickHo
|
||||
});
|
||||
}
|
||||
|
||||
export function getSessionsCountQueryBuilder(
|
||||
ch: ClickhouseReader,
|
||||
settings?: ClickHouseSettings
|
||||
) {
|
||||
export function getSessionsCountQueryBuilder(ch: ClickhouseReader, settings?: ClickHouseSettings) {
|
||||
return ch.queryBuilder({
|
||||
name: "getSessionsCount",
|
||||
baseQuery: "SELECT count() as count FROM trigger_dev.sessions_v1 FINAL",
|
||||
@@ -175,10 +172,7 @@ export const SessionTagsQueryResult = z.object({
|
||||
|
||||
export type SessionTagsQueryResult = z.infer<typeof SessionTagsQueryResult>;
|
||||
|
||||
export function getSessionTagsQueryBuilder(
|
||||
ch: ClickhouseReader,
|
||||
settings?: ClickHouseSettings
|
||||
) {
|
||||
export function getSessionTagsQueryBuilder(ch: ClickhouseReader, settings?: ClickHouseSettings) {
|
||||
return ch.queryBuilder({
|
||||
name: "getSessionTags",
|
||||
baseQuery: "SELECT DISTINCT arrayJoin(tags) as tag FROM trigger_dev.sessions_v1",
|
||||
|
||||
@@ -213,10 +213,7 @@ export function insertTaskEventsV2(ch: ClickhouseWriter, settings?: ClickHouseSe
|
||||
});
|
||||
}
|
||||
|
||||
export function getTraceSummaryQueryBuilderV2(
|
||||
ch: ClickhouseReader,
|
||||
settings?: ClickHouseSettings
|
||||
) {
|
||||
export function getTraceSummaryQueryBuilderV2(ch: ClickhouseReader, settings?: ClickHouseSettings) {
|
||||
return ch.queryBuilderFast<TaskEventSummaryV1Result>({
|
||||
name: "getTraceEventsV2",
|
||||
table: "trigger_dev.task_events_v2",
|
||||
@@ -258,10 +255,7 @@ export function getTraceDetailedSummaryQueryBuilderV2(
|
||||
});
|
||||
}
|
||||
|
||||
export function getSpanDetailsQueryBuilderV2(
|
||||
ch: ClickhouseReader,
|
||||
settings?: ClickHouseSettings
|
||||
) {
|
||||
export function getSpanDetailsQueryBuilderV2(ch: ClickhouseReader, settings?: ClickHouseSettings) {
|
||||
return ch.queryBuilder({
|
||||
name: "getSpanDetailsV2",
|
||||
baseQuery:
|
||||
@@ -283,7 +277,6 @@ export function getTraceEventsForExportQueryBuilderV2(
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Search Table Query Builders (for logs page, using task_events_search_v1)
|
||||
// ============================================================================
|
||||
@@ -350,7 +343,7 @@ export const LogDetailV2Result = z.object({
|
||||
kind: z.string(),
|
||||
status: z.string(),
|
||||
duration: z.number().or(z.string()),
|
||||
attributes_text: z.string()
|
||||
attributes_text: z.string(),
|
||||
});
|
||||
|
||||
export type LogDetailV2Result = z.output<typeof LogDetailV2Result>;
|
||||
@@ -376,4 +369,4 @@ export function getLogDetailQueryBuilderV2(ch: ClickhouseReader) {
|
||||
"attributes_text",
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,9 +556,7 @@ describe("Task Runs V2", () => {
|
||||
null,
|
||||
];
|
||||
|
||||
const childA_v2: TaskRunInsertArray = [
|
||||
...childA_v1,
|
||||
];
|
||||
const childA_v2: TaskRunInsertArray = [...childA_v1];
|
||||
childA_v2[TASK_RUN_INDEX.status] = "COMPLETED_SUCCESSFULLY";
|
||||
childA_v2[TASK_RUN_INDEX._version] = "2";
|
||||
|
||||
@@ -676,24 +674,18 @@ describe("Task Runs V2", () => {
|
||||
null,
|
||||
];
|
||||
|
||||
const childDeleted_v2: TaskRunInsertArray = [
|
||||
...childDeleted_v1,
|
||||
];
|
||||
const childDeleted_v2: TaskRunInsertArray = [...childDeleted_v1];
|
||||
childDeleted_v2[TASK_RUN_INDEX._version] = "2";
|
||||
childDeleted_v2[TASK_RUN_INDEX._is_deleted] = 1;
|
||||
|
||||
const childWrongRoot: TaskRunInsertArray = [
|
||||
...childB,
|
||||
];
|
||||
const childWrongRoot: TaskRunInsertArray = [...childB];
|
||||
childWrongRoot[TASK_RUN_INDEX.run_id] = "child_wrong_root";
|
||||
childWrongRoot[TASK_RUN_INDEX.friendly_id] = "run_child_wrong_root";
|
||||
childWrongRoot[TASK_RUN_INDEX.root_run_id] = "other_root";
|
||||
childWrongRoot[TASK_RUN_INDEX.parent_run_id] = "other_root";
|
||||
childWrongRoot[TASK_RUN_INDEX.span_id] = "span_child_wrong_root";
|
||||
|
||||
const childOld: TaskRunInsertArray = [
|
||||
...childB,
|
||||
];
|
||||
const childOld: TaskRunInsertArray = [...childB];
|
||||
childOld[TASK_RUN_INDEX.run_id] = "child_old";
|
||||
childOld[TASK_RUN_INDEX.created_at] = oldCreatedAt;
|
||||
childOld[TASK_RUN_INDEX.updated_at] = oldCreatedAt;
|
||||
|
||||
@@ -1563,52 +1563,49 @@ describe("Field Mapping Tests", () => {
|
||||
}
|
||||
);
|
||||
|
||||
clickhouseTest(
|
||||
"should handle field mapping with IN clause",
|
||||
async ({ clickhouseContainer }) => {
|
||||
const client = new ClickhouseClient({
|
||||
name: "test",
|
||||
url: clickhouseContainer.getConnectionUrl(),
|
||||
});
|
||||
clickhouseTest("should handle field mapping with IN clause", async ({ clickhouseContainer }) => {
|
||||
const client = new ClickhouseClient({
|
||||
name: "test",
|
||||
url: clickhouseContainer.getConnectionUrl(),
|
||||
});
|
||||
|
||||
const insert = insertTaskRuns(client, { async_insert: 0 });
|
||||
const insert = insertTaskRuns(client, { async_insert: 0 });
|
||||
|
||||
// Insert test runs with different projects
|
||||
await insert([
|
||||
createTaskRun({
|
||||
run_id: "run_fm_in1",
|
||||
project_id: "proj_tenant1",
|
||||
status: "COMPLETED_SUCCESSFULLY",
|
||||
}),
|
||||
createTaskRun({
|
||||
run_id: "run_fm_in2",
|
||||
project_id: "proj_other",
|
||||
organization_id: "org_tenant1",
|
||||
status: "PENDING",
|
||||
}),
|
||||
]);
|
||||
// Insert test runs with different projects
|
||||
await insert([
|
||||
createTaskRun({
|
||||
run_id: "run_fm_in1",
|
||||
project_id: "proj_tenant1",
|
||||
status: "COMPLETED_SUCCESSFULLY",
|
||||
}),
|
||||
createTaskRun({
|
||||
run_id: "run_fm_in2",
|
||||
project_id: "proj_other",
|
||||
organization_id: "org_tenant1",
|
||||
status: "PENDING",
|
||||
}),
|
||||
]);
|
||||
|
||||
// Query using IN clause with external project_ref values
|
||||
const [error, result] = await executeTSQL(client, {
|
||||
name: "test-field-mapping-in",
|
||||
query:
|
||||
"SELECT run_id FROM task_runs WHERE project_ref IN ('my-project-ref', 'other-project')",
|
||||
schema: z.object({ run_id: z.string() }),
|
||||
enforcedWhereClause: {
|
||||
organization_id: { op: "eq", value: "org_tenant1" },
|
||||
// Query using IN clause with external project_ref values
|
||||
const [error, result] = await executeTSQL(client, {
|
||||
name: "test-field-mapping-in",
|
||||
query:
|
||||
"SELECT run_id FROM task_runs WHERE project_ref IN ('my-project-ref', 'other-project')",
|
||||
schema: z.object({ run_id: z.string() }),
|
||||
enforcedWhereClause: {
|
||||
organization_id: { op: "eq", value: "org_tenant1" },
|
||||
},
|
||||
tableSchema: [fieldMappingSchema],
|
||||
fieldMappings: {
|
||||
project: {
|
||||
proj_tenant1: "my-project-ref",
|
||||
proj_other: "other-project",
|
||||
},
|
||||
tableSchema: [fieldMappingSchema],
|
||||
fieldMappings: {
|
||||
project: {
|
||||
proj_tenant1: "my-project-ref",
|
||||
proj_other: "other-project",
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
expect(error).toBeNull();
|
||||
expect(result?.rows).toHaveLength(2);
|
||||
expect(result?.rows?.map((r) => r.run_id).sort()).toEqual(["run_fm_in1", "run_fm_in2"]);
|
||||
}
|
||||
);
|
||||
expect(error).toBeNull();
|
||||
expect(result?.rows).toHaveLength(2);
|
||||
expect(result?.rows?.map((r) => r.run_id).sort()).toEqual(["run_fm_in1", "run_fm_in2"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -62,7 +62,11 @@ class HttpTransport {
|
||||
return options?.signal ?? AbortSignal.timeout(this.opts.timeoutMs);
|
||||
}
|
||||
|
||||
async post<T = unknown>(path: string, body: unknown, options?: RequestOptions): Promise<T | undefined> {
|
||||
async post<T = unknown>(
|
||||
path: string,
|
||||
body: unknown,
|
||||
options?: RequestOptions
|
||||
): Promise<T | undefined> {
|
||||
const url = `${this.opts.gatewayUrl}${path}`;
|
||||
|
||||
const response = await fetch(url, {
|
||||
|
||||
@@ -175,4 +175,4 @@
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,10 +303,7 @@
|
||||
"compositePrimaryKeys": {
|
||||
"chat_turn_evals_chat_id_turn_pk": {
|
||||
"name": "chat_turn_evals_chat_id_turn_pk",
|
||||
"columns": [
|
||||
"chat_id",
|
||||
"turn"
|
||||
]
|
||||
"columns": ["chat_id", "turn"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
@@ -441,4 +438,4 @@
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,4 @@
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,7 @@ function normalizeConnectionString(value) {
|
||||
}
|
||||
}
|
||||
|
||||
const journalPath = join(
|
||||
dirname(fileURLToPath(import.meta.url)),
|
||||
"drizzle/meta/_journal.json"
|
||||
);
|
||||
const journalPath = join(dirname(fileURLToPath(import.meta.url)), "drizzle/meta/_journal.json");
|
||||
const sql = postgres(normalizeConnectionString(connectionString), {
|
||||
max: 1,
|
||||
prepare: false,
|
||||
@@ -59,9 +56,7 @@ async function main() {
|
||||
}
|
||||
|
||||
const pending = entries.filter((e) => e.when > lastAppliedAt);
|
||||
console.log(
|
||||
`${entries.length} migration(s) found, ${entries.length - pending.length} applied`
|
||||
);
|
||||
console.log(`${entries.length} migration(s) found, ${entries.length - pending.length} applied`);
|
||||
|
||||
if (pending.length > 0) {
|
||||
console.log(`${pending.length} pending migration(s):`);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { and, desc, eq, isNull, sql } from "drizzle-orm";
|
||||
import type { DashboardAgentDb } from "./client.js";
|
||||
import { chats, chatSessions, chatTurnEvals, type ChatSession, type NewChatTurnEval } from "./schema.js";
|
||||
import {
|
||||
chats,
|
||||
chatSessions,
|
||||
chatTurnEvals,
|
||||
type ChatSession,
|
||||
type NewChatTurnEval,
|
||||
} from "./schema.js";
|
||||
|
||||
/**
|
||||
* The access-pattern layer. Every query that touches user data is scoped by
|
||||
@@ -64,11 +70,7 @@ export async function getChatMessages(
|
||||
.select({ messages: chats.messages })
|
||||
.from(chats)
|
||||
.where(
|
||||
and(
|
||||
eq(chats.id, params.chatId),
|
||||
eq(chats.userId, params.userId),
|
||||
isNull(chats.deletedAt)
|
||||
)
|
||||
and(eq(chats.id, params.chatId), eq(chats.userId, params.userId), isNull(chats.deletedAt))
|
||||
)
|
||||
.limit(1);
|
||||
return rows[0]?.messages ?? null;
|
||||
@@ -175,11 +177,7 @@ export async function setChatTitleIfDefault(
|
||||
.update(chats)
|
||||
.set({ title: params.title, updatedAt: sql`now()` })
|
||||
.where(
|
||||
and(
|
||||
eq(chats.id, params.chatId),
|
||||
eq(chats.title, DEFAULT_CHAT_TITLE),
|
||||
isNull(chats.deletedAt)
|
||||
)
|
||||
and(eq(chats.id, params.chatId), eq(chats.title, DEFAULT_CHAT_TITLE), isNull(chats.deletedAt))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,12 @@ const Verdict = z.object({
|
||||
.min(1)
|
||||
.max(5)
|
||||
.describe("Does the answer directly address the user's question? 5 = fully, 1 = not at all."),
|
||||
concise: z.number().int().min(1).max(5).describe("Direct and free of padding. Do not reward length."),
|
||||
concise: z
|
||||
.number()
|
||||
.int()
|
||||
.min(1)
|
||||
.max(5)
|
||||
.describe("Direct and free of padding. Do not reward length."),
|
||||
});
|
||||
|
||||
const JUDGE_SYSTEM = [
|
||||
@@ -246,48 +251,43 @@ const TOOL_CASES: Array<{ question: string; expect: string }> = [
|
||||
const TOOL_SELECTION_THRESHOLD = 0.83; // tolerate ~2/12 misses; a trend reds the suite
|
||||
|
||||
describe.skipIf(!HAS_KEY)("dashboardAgent evals (real model)", () => {
|
||||
it(
|
||||
"tool selection: picks the right tool for the question",
|
||||
async () => {
|
||||
const results: Array<{ question: string; expected: string; got: string; ok: boolean }> = [];
|
||||
for (const c of TOOL_CASES) {
|
||||
const { calls } = await runCase(c.question);
|
||||
const got = calls[0]?.tool ?? "(none)";
|
||||
results.push({ question: c.question, expected: c.expect, got, ok: got === c.expect });
|
||||
}
|
||||
it("tool selection: picks the right tool for the question", async () => {
|
||||
const results: Array<{ question: string; expected: string; got: string; ok: boolean }> = [];
|
||||
for (const c of TOOL_CASES) {
|
||||
const { calls } = await runCase(c.question);
|
||||
const got = calls[0]?.tool ?? "(none)";
|
||||
results.push({ question: c.question, expected: c.expect, got, ok: got === c.expect });
|
||||
}
|
||||
|
||||
const passed = results.filter((r) => r.ok).length;
|
||||
const rate = passed / results.length;
|
||||
// Surface the full table so a failing case is diagnosable, not just a number.
|
||||
// process.stdout.write (not console.log) so it survives vitest's console intercept.
|
||||
process.stdout.write(
|
||||
`\ntool selection: ${passed}/${results.length} (${(rate * 100).toFixed(0)}%)\n` +
|
||||
results
|
||||
.map((r) => ` ${r.ok ? "PASS" : "FAIL"} ${r.got.padEnd(18)} (want ${r.expected}) ${r.question}`)
|
||||
.join("\n") +
|
||||
"\n"
|
||||
);
|
||||
const passed = results.filter((r) => r.ok).length;
|
||||
const rate = passed / results.length;
|
||||
// Surface the full table so a failing case is diagnosable, not just a number.
|
||||
// process.stdout.write (not console.log) so it survives vitest's console intercept.
|
||||
process.stdout.write(
|
||||
`\ntool selection: ${passed}/${results.length} (${(rate * 100).toFixed(0)}%)\n` +
|
||||
results
|
||||
.map(
|
||||
(r) =>
|
||||
` ${r.ok ? "PASS" : "FAIL"} ${r.got.padEnd(18)} (want ${r.expected}) ${r.question}`
|
||||
)
|
||||
.join("\n") +
|
||||
"\n"
|
||||
);
|
||||
|
||||
expect(rate).toBeGreaterThanOrEqual(TOOL_SELECTION_THRESHOLD);
|
||||
},
|
||||
180_000
|
||||
);
|
||||
expect(rate).toBeGreaterThanOrEqual(TOOL_SELECTION_THRESHOLD);
|
||||
}, 180_000);
|
||||
|
||||
it(
|
||||
"answer quality: grounded and on-question (LLM judge)",
|
||||
async () => {
|
||||
const question = "What errors are happening in this environment? Summarize the top ones.";
|
||||
const { calls, answer } = await runCase(question);
|
||||
it("answer quality: grounded and on-question (LLM judge)", async () => {
|
||||
const question = "What errors are happening in this environment? Summarize the top ones.";
|
||||
const { calls, answer } = await runCase(question);
|
||||
|
||||
expect(calls[0]?.tool).toBe("list_errors");
|
||||
expect(answer.length).toBeGreaterThan(0);
|
||||
expect(calls[0]?.tool).toBe("list_errors");
|
||||
expect(answer.length).toBeGreaterThan(0);
|
||||
|
||||
const verdict = await judge({ question, toolData: FIXTURES.list_errors, answer });
|
||||
process.stdout.write(`\nanswer:\n${answer}\n\njudge: ${JSON.stringify(verdict)}\n`);
|
||||
const verdict = await judge({ question, toolData: FIXTURES.list_errors, answer });
|
||||
process.stdout.write(`\nanswer:\n${answer}\n\njudge: ${JSON.stringify(verdict)}\n`);
|
||||
|
||||
expect(verdict.grounded).toBeGreaterThanOrEqual(4);
|
||||
expect(verdict.answersQuestion).toBeGreaterThanOrEqual(4);
|
||||
},
|
||||
120_000
|
||||
);
|
||||
expect(verdict.grounded).toBeGreaterThanOrEqual(4);
|
||||
expect(verdict.answersQuestion).toBeGreaterThanOrEqual(4);
|
||||
}, 120_000);
|
||||
});
|
||||
|
||||
@@ -302,7 +302,9 @@ describe("buildDashboardAgentTools", () => {
|
||||
category: "user_code_error",
|
||||
likelyCause: "processOrder throws when items is empty.",
|
||||
confidence: "high",
|
||||
evidence: [{ type: "error", detail: "Error: order has no items", reference: "run_abc123" }],
|
||||
evidence: [
|
||||
{ type: "error", detail: "Error: order has no items", reference: "run_abc123" },
|
||||
],
|
||||
nextSteps: ["Validate the payload before triggering."],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -45,8 +45,7 @@ let dbClient: DashboardAgentDbClient | undefined;
|
||||
|
||||
function getDb(): DashboardAgentDbClient {
|
||||
if (!dbClient) {
|
||||
const connectionString =
|
||||
process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
|
||||
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
|
||||
if (!connectionString) {
|
||||
throw new Error(
|
||||
"DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the dashboard agent"
|
||||
@@ -182,7 +181,9 @@ async function generateAndSaveTitle(
|
||||
const { text } = await generateText({
|
||||
model:
|
||||
locals.get(dashboardAgentModelKey) ??
|
||||
registry.languageModel((resolved.model ?? "anthropic:claude-haiku-4-5") as `anthropic:${string}`),
|
||||
registry.languageModel(
|
||||
(resolved.model ?? "anthropic:claude-haiku-4-5") as `anthropic:${string}`
|
||||
),
|
||||
system: resolved.text,
|
||||
prompt: userText,
|
||||
...resolved.toAISDKTelemetry(),
|
||||
@@ -373,7 +374,9 @@ export const dashboardAgent = chat.agent({
|
||||
// prompt's model through the provider registry.
|
||||
model:
|
||||
locals.get(dashboardAgentModelKey) ??
|
||||
registry.languageModel((resolved.model ?? "anthropic:claude-sonnet-4-6") as `anthropic:${string}`),
|
||||
registry.languageModel(
|
||||
(resolved.model ?? "anthropic:claude-sonnet-4-6") as `anthropic:${string}`
|
||||
),
|
||||
messages,
|
||||
abortSignal: signal,
|
||||
// toStreamTextOptions() defaults to a single step; override so the model
|
||||
|
||||
@@ -25,10 +25,11 @@ const JUDGE_MODEL = "claude-sonnet-4-6";
|
||||
let dbClient: DashboardAgentDbClient | undefined;
|
||||
function getEvalDb(): DashboardAgentDbClient {
|
||||
if (!dbClient) {
|
||||
const connectionString =
|
||||
process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
|
||||
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
|
||||
if (!connectionString) {
|
||||
throw new Error("DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the eval task");
|
||||
throw new Error(
|
||||
"DASHBOARD_AGENT_DATABASE_URL (or DATABASE_URL) must be set for the eval task"
|
||||
);
|
||||
}
|
||||
dbClient = createDashboardAgentDb(connectionString, { max: 2 });
|
||||
}
|
||||
@@ -77,8 +78,15 @@ const TurnEval = z.object({
|
||||
.int()
|
||||
.min(1)
|
||||
.max(5)
|
||||
.describe("Does the answer use only facts from the tool results? Penalize invented ids/counts/status. 5 = fully grounded."),
|
||||
answered: z.number().int().min(1).max(5).describe("Does it directly answer the question? 5 = fully."),
|
||||
.describe(
|
||||
"Does the answer use only facts from the tool results? Penalize invented ids/counts/status. 5 = fully grounded."
|
||||
),
|
||||
answered: z
|
||||
.number()
|
||||
.int()
|
||||
.min(1)
|
||||
.max(5)
|
||||
.describe("Does it directly answer the question? 5 = fully."),
|
||||
concise: z.number().int().min(1).max(5).describe("Direct, no padding. Do not reward length."),
|
||||
// Insight classification.
|
||||
intentCategory: z
|
||||
@@ -86,17 +94,25 @@ const TurnEval = z.object({
|
||||
.describe("What the user was trying to do."),
|
||||
outcome: z
|
||||
.enum(["resolved", "partial", "unresolved", "deflected"])
|
||||
.describe("Did the agent actually help? deflected = sent the user elsewhere without answering."),
|
||||
.describe(
|
||||
"Did the agent actually help? deflected = sent the user elsewhere without answering."
|
||||
),
|
||||
sentiment: z.enum(["positive", "neutral", "negative", "frustrated"]),
|
||||
capabilityGap: z
|
||||
.boolean()
|
||||
.describe("The agent lacked a tool, data, or permission needed to fully help."),
|
||||
docsGap: z.boolean().describe("A how-to the agent answered weakly or that better docs would solve."),
|
||||
docsGap: z
|
||||
.boolean()
|
||||
.describe("A how-to the agent answered weakly or that better docs would solve."),
|
||||
supportOpportunity: z
|
||||
.boolean()
|
||||
.describe("The user seems stuck, blocked, or frustrated and would benefit from a human follow-up."),
|
||||
.describe(
|
||||
"The user seems stuck, blocked, or frustrated and would benefit from a human follow-up."
|
||||
),
|
||||
featureRequest: z.boolean().describe("The user wants something the product does not do."),
|
||||
topics: z.array(z.string()).describe("1-3 short topic tags, e.g. 'concurrency', 'failed deploys'."),
|
||||
topics: z
|
||||
.array(z.string())
|
||||
.describe("1-3 short topic tags, e.g. 'concurrency', 'failed deploys'."),
|
||||
signals: z
|
||||
.array(
|
||||
z.object({
|
||||
|
||||
@@ -28,7 +28,8 @@ export const systemPrompt = prompts.define({
|
||||
// repo, so the agent has the source-reading tools too.
|
||||
export const codeSystemPrompt = prompts.define({
|
||||
id: "dashboard-agent-system-code",
|
||||
description: "System prompt for the in-dashboard agent when the project's GitHub repo is connected.",
|
||||
description:
|
||||
"System prompt for the in-dashboard agent when the project's GitHub repo is connected.",
|
||||
model: `anthropic:${DASHBOARD_AGENT_MODEL}`,
|
||||
content: DASHBOARD_AGENT_CODE_SYSTEM_PROMPT,
|
||||
});
|
||||
|
||||
@@ -67,7 +67,12 @@ afterAll(async () => {
|
||||
describe("repo-tools", () => {
|
||||
it("get_repo_info returns the connected repo and pinned commit", async () => {
|
||||
const res = await call(tools.get_repo_info, {});
|
||||
expect(res).toEqual({ owner: "acme", repo: "demo", sha: "deadbeefdeadbeef", defaultBranch: "main" });
|
||||
expect(res).toEqual({
|
||||
owner: "acme",
|
||||
repo: "demo",
|
||||
sha: "deadbeefdeadbeef",
|
||||
defaultBranch: "main",
|
||||
});
|
||||
});
|
||||
|
||||
it("read_file reads a file from the workspace", async () => {
|
||||
@@ -78,7 +83,11 @@ describe("repo-tools", () => {
|
||||
});
|
||||
|
||||
it("read_file honors a line range", async () => {
|
||||
const res: any = await call(tools.read_file, { path: "src/trigger/order.ts", startLine: 2, endLine: 2 });
|
||||
const res: any = await call(tools.read_file, {
|
||||
path: "src/trigger/order.ts",
|
||||
startLine: 2,
|
||||
endLine: 2,
|
||||
});
|
||||
expect(res.content).toBe("const LIMIT = 10000;");
|
||||
expect(res.startLine).toBe(2);
|
||||
expect(res.endLine).toBe(2);
|
||||
@@ -99,7 +108,10 @@ describe("repo-tools", () => {
|
||||
it("read_file with runId reads the run's pinned commit", async () => {
|
||||
const def: any = await call(tools.read_file, { path: "src/trigger/order.ts" });
|
||||
expect(def.content).toContain("const LIMIT = 10000;");
|
||||
const pinned: any = await call(tools.read_file, { path: "src/trigger/order.ts", runId: "run_pinned" });
|
||||
const pinned: any = await call(tools.read_file, {
|
||||
path: "src/trigger/order.ts",
|
||||
runId: "run_pinned",
|
||||
});
|
||||
expect(pinned.error).toBeUndefined();
|
||||
expect(pinned.content).toContain("const LIMIT = 5000;");
|
||||
});
|
||||
@@ -110,14 +122,19 @@ describe("repo-tools", () => {
|
||||
});
|
||||
|
||||
it("read_file with an unresolvable runId errors instead of falling back", async () => {
|
||||
const res: any = await call(tools.read_file, { path: "src/trigger/order.ts", runId: "run_unknown" });
|
||||
const res: any = await call(tools.read_file, {
|
||||
path: "src/trigger/order.ts",
|
||||
runId: "run_unknown",
|
||||
});
|
||||
expect(res.error).toMatch(/Couldn't resolve the source/);
|
||||
});
|
||||
|
||||
it.runIf(hasRg)("search_code finds a match (and does not hang on stdin)", async () => {
|
||||
const res: any = await call(tools.search_code, { query: "const LIMIT" });
|
||||
expect(res.error).toBeUndefined();
|
||||
expect(res.matches.some((m: any) => String(m.file).includes("order.ts") && /LIMIT/.test(m.text))).toBe(true);
|
||||
expect(
|
||||
res.matches.some((m: any) => String(m.file).includes("order.ts") && /LIMIT/.test(m.text))
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it.runIf(hasRg)("list_files lists workspace files", async () => {
|
||||
|
||||
@@ -86,7 +86,8 @@ async function ensureWorkspace(snapshot: RepoSnapshot): Promise<string> {
|
||||
const length = Number(res.headers.get("content-length") ?? 0);
|
||||
if (length > MAX_ARCHIVE_BYTES) throw new Error(`archive too large (${length} bytes)`);
|
||||
const bytes = new Uint8Array(await res.arrayBuffer());
|
||||
if (bytes.length > MAX_ARCHIVE_BYTES) throw new Error(`archive too large (${bytes.length} bytes)`);
|
||||
if (bytes.length > MAX_ARCHIVE_BYTES)
|
||||
throw new Error(`archive too large (${bytes.length} bytes)`);
|
||||
|
||||
const scratch = await mkdtemp(join(tmpdir(), "dashboard-agent-tar-"));
|
||||
tarPath = join(scratch, "repo.tar.gz");
|
||||
@@ -149,7 +150,8 @@ export function buildRepoTools(
|
||||
// (resolved server-side), otherwise the default tracked-branch snapshot.
|
||||
async function snapshotFor(runId?: string): Promise<RepoSnapshot | { error: string }> {
|
||||
if (!runId) return defaultSnapshot;
|
||||
if (!resolveRunSnapshot) return { error: "Reading a specific run's source isn't available here." };
|
||||
if (!resolveRunSnapshot)
|
||||
return { error: "Reading a specific run's source isn't available here." };
|
||||
const snap = await resolveRunSnapshot(runId);
|
||||
return (
|
||||
snap ?? {
|
||||
@@ -177,7 +179,12 @@ export function buildRepoTools(
|
||||
execute: async ({ runId }) => {
|
||||
const snap = await snapshotFor(runId);
|
||||
if ("error" in snap) return snap;
|
||||
return { owner: snap.owner, repo: snap.repo, sha: snap.sha, defaultBranch: snap.defaultBranch };
|
||||
return {
|
||||
owner: snap.owner,
|
||||
repo: snap.repo,
|
||||
sha: snap.sha,
|
||||
defaultBranch: snap.defaultBranch,
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -199,8 +206,14 @@ export function buildRepoTools(
|
||||
const cwd = realSub ?? sub;
|
||||
try {
|
||||
const { stdout } = await execFileAsync("rg", args, { cwd, maxBuffer: 16 * 1024 * 1024 });
|
||||
const files = stdout.split("\n").filter(Boolean).map((f) => relative(workdir, resolve(cwd, f)));
|
||||
return { files: files.slice(0, MAX_LIST_FILES), truncated: files.length > MAX_LIST_FILES };
|
||||
const files = stdout
|
||||
.split("\n")
|
||||
.filter(Boolean)
|
||||
.map((f) => relative(workdir, resolve(cwd, f)));
|
||||
return {
|
||||
files: files.slice(0, MAX_LIST_FILES),
|
||||
truncated: files.length > MAX_LIST_FILES,
|
||||
};
|
||||
} catch (error) {
|
||||
// rg exits 1 when there are no matches; treat as empty, not an error.
|
||||
if ((error as { code?: number }).code === 1) return { files: [], truncated: false };
|
||||
@@ -256,14 +269,19 @@ export function buildRepoTools(
|
||||
// in a spawned process) and blocks forever. The "." makes it search files.
|
||||
args.push("-e", query, ".");
|
||||
try {
|
||||
const { stdout } = await execFileAsync("rg", args, { cwd: workdir, maxBuffer: 16 * 1024 * 1024 });
|
||||
const { stdout } = await execFileAsync("rg", args, {
|
||||
cwd: workdir,
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
});
|
||||
const matches = stdout
|
||||
.split("\n")
|
||||
.filter(Boolean)
|
||||
.slice(0, cap)
|
||||
.map((line) => {
|
||||
const m = line.match(/^([^:]+):(\d+):(.*)$/);
|
||||
return m ? { file: m[1], line: Number(m[2]), text: m[3].slice(0, 300) } : { text: line };
|
||||
return m
|
||||
? { file: m[1], line: Number(m[2]), text: m[3].slice(0, 300) }
|
||||
: { text: line };
|
||||
});
|
||||
return { matches, truncated: matches.length >= cap };
|
||||
} catch (error) {
|
||||
|
||||
@@ -48,12 +48,20 @@ export const listRunsSchema = tool({
|
||||
errorId: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Only runs that hit this error group (an error_... id from list_errors/get_error)."),
|
||||
.describe(
|
||||
"Only runs that hit this error group (an error_... id from list_errors/get_error)."
|
||||
),
|
||||
period: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Relative window, e.g. 1h, 24h, 7d. Max 30d; larger values are capped at 30d."),
|
||||
limit: z.number().int().positive().max(50).optional().describe("Max runs to return (default 10)."),
|
||||
limit: z
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.max(50)
|
||||
.optional()
|
||||
.describe("Max runs to return (default 10)."),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -119,7 +127,9 @@ export const getQuerySchemaSchema = tool({
|
||||
table: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("A table name (e.g. 'runs') to get its columns. Omit to list the available tables."),
|
||||
.describe(
|
||||
"A table name (e.g. 'runs') to get its columns. Omit to list the available tables."
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -129,11 +139,15 @@ export const runQuerySchema = tool({
|
||||
inputSchema: z.object({
|
||||
query: z
|
||||
.string()
|
||||
.describe("The TRQL query. A read-only SELECT over runs / metrics / llm_metrics / llm_models."),
|
||||
.describe(
|
||||
"The TRQL query. A read-only SELECT over runs / metrics / llm_metrics / llm_models."
|
||||
),
|
||||
period: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."),
|
||||
.describe(
|
||||
"Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -141,7 +155,9 @@ export const askSupportSchema = tool({
|
||||
description:
|
||||
"Ask the Trigger.dev support assistant a question about how Trigger.dev works: docs, concepts, features, configuration, best practices, and troubleshooting how-tos (e.g. 'how do retries work?', 'how do I set a concurrency limit?', 'does Trigger.dev support cron schedules?'). Use this for product/knowledge questions, NOT for the user's own runs, errors, or data (use the read and query tools for those). Returns a composed answer.",
|
||||
inputSchema: z.object({
|
||||
question: z.string().describe("The user's question about how Trigger.dev works, in natural language."),
|
||||
question: z
|
||||
.string()
|
||||
.describe("The user's question about how Trigger.dev works, in natural language."),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -183,7 +199,9 @@ export const diagnosisBlockSchema = z.object({
|
||||
.describe("Your classification of the root cause."),
|
||||
likelyCause: z
|
||||
.string()
|
||||
.describe("The most probable root cause, in specific terms — name the code, config, or dependency."),
|
||||
.describe(
|
||||
"The most probable root cause, in specific terms — name the code, config, or dependency."
|
||||
),
|
||||
confidence: z
|
||||
.enum(["high", "medium", "low"])
|
||||
.describe("How confident you are in this diagnosis given the evidence. Be honest."),
|
||||
@@ -208,7 +226,9 @@ export const diagnosisBlockSchema = z.object({
|
||||
),
|
||||
})
|
||||
)
|
||||
.describe("The concrete signals behind the diagnosis. Cite real ids, spans, versions, or file:line."),
|
||||
.describe(
|
||||
"The concrete signals behind the diagnosis. Cite real ids, spans, versions, or file:line."
|
||||
),
|
||||
impact: z
|
||||
.string()
|
||||
.optional()
|
||||
@@ -220,7 +240,9 @@ export const diagnosisBlockSchema = z.object({
|
||||
label: z.string().describe("Button text, e.g. 'View run' or 'Read the retries docs'."),
|
||||
kind: z
|
||||
.enum(["view_run", "docs"])
|
||||
.describe("view_run links to a run page in this environment; docs opens an external URL."),
|
||||
.describe(
|
||||
"view_run links to a run page in this environment; docs opens an external URL."
|
||||
),
|
||||
target: z.string().describe("For view_run: a run id (run_...). For docs: an https URL."),
|
||||
})
|
||||
)
|
||||
@@ -244,13 +266,19 @@ export const chartBlockSchema = z.object({
|
||||
period: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."),
|
||||
.describe(
|
||||
"Time window shorthand like '24h', '7d', '30d' (max 30d), applied to the table's time column."
|
||||
),
|
||||
chartType: z
|
||||
.enum(["line", "bar"])
|
||||
.describe("line for trends over time, bar for comparing categories. Stack with `stacked` for composition."),
|
||||
.describe(
|
||||
"line for trends over time, bar for comparing categories. Stack with `stacked` for composition."
|
||||
),
|
||||
xAxisColumn: z
|
||||
.string()
|
||||
.describe("The result column for the x-axis: a time bucket (for line) or a category (for bar)."),
|
||||
.describe(
|
||||
"The result column for the x-axis: a time bucket (for line) or a category (for bar)."
|
||||
),
|
||||
yAxisColumns: z
|
||||
.array(z.string())
|
||||
.min(1)
|
||||
@@ -258,15 +286,23 @@ export const chartBlockSchema = z.object({
|
||||
groupByColumn: z
|
||||
.string()
|
||||
.nullish()
|
||||
.describe("Optional result column to split a single yAxisColumn into one series per distinct value."),
|
||||
stacked: z.boolean().optional().describe("Stack the series (cumulative/composition). Default false."),
|
||||
.describe(
|
||||
"Optional result column to split a single yAxisColumn into one series per distinct value."
|
||||
),
|
||||
stacked: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.describe("Stack the series (cumulative/composition). Default false."),
|
||||
aggregation: z
|
||||
.enum(["sum", "avg", "count", "min", "max"])
|
||||
.optional()
|
||||
.describe("How to combine values that share an x point. Default sum."),
|
||||
});
|
||||
|
||||
export const viewBlockSchema = z.discriminatedUnion("type", [diagnosisBlockSchema, chartBlockSchema]);
|
||||
export const viewBlockSchema = z.discriminatedUnion("type", [
|
||||
diagnosisBlockSchema,
|
||||
chartBlockSchema,
|
||||
]);
|
||||
|
||||
export type DiagnosisBlock = z.infer<typeof diagnosisBlockSchema>;
|
||||
export type ChartBlock = z.infer<typeof chartBlockSchema>;
|
||||
@@ -303,7 +339,10 @@ export const listFilesSchema = tool({
|
||||
"List source files in the connected repository (respecting .gitignore). Optionally filter by a glob like '**/*.ts' or scope to a subdirectory. Use this to find where something lives before reading it.",
|
||||
inputSchema: z.object({
|
||||
glob: z.string().optional().describe("Glob filter, e.g. 'src/**/*.ts' or '*.json'."),
|
||||
path: z.string().optional().describe("Subdirectory (relative to repo root) to scope the listing to."),
|
||||
path: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Subdirectory (relative to repo root) to scope the listing to."),
|
||||
runId: runIdField,
|
||||
}),
|
||||
});
|
||||
@@ -312,7 +351,9 @@ export const readFileSchema = tool({
|
||||
description:
|
||||
"Read a file from the connected repository by its path relative to the repo root. Optionally restrict to a line range. Use this to read the actual task source behind a run or error.",
|
||||
inputSchema: z.object({
|
||||
path: z.string().describe("File path relative to the repo root, e.g. src/trigger/processOrder.ts."),
|
||||
path: z
|
||||
.string()
|
||||
.describe("File path relative to the repo root, e.g. src/trigger/processOrder.ts."),
|
||||
startLine: z.number().int().positive().optional().describe("First line to include (1-based)."),
|
||||
endLine: z.number().int().positive().optional().describe("Last line to include (1-based)."),
|
||||
runId: runIdField,
|
||||
@@ -325,7 +366,13 @@ export const searchCodeSchema = tool({
|
||||
inputSchema: z.object({
|
||||
query: z.string().describe("The ripgrep pattern to search for."),
|
||||
glob: z.string().optional().describe("Restrict the search to files matching this glob."),
|
||||
maxResults: z.number().int().positive().max(80).optional().describe("Max matches to return (default 40)."),
|
||||
maxResults: z
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.max(80)
|
||||
.optional()
|
||||
.describe("Max matches to return (default 40)."),
|
||||
runId: runIdField,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -174,7 +174,11 @@ function curateTrace(data: unknown) {
|
||||
for (const child of span.children ?? []) walk(child, depth + 1);
|
||||
};
|
||||
walk(root, 0);
|
||||
return { traceId: (data as any)?.trace?.traceId, spans, truncated: spans.length >= MAX_TRACE_SPANS };
|
||||
return {
|
||||
traceId: (data as any)?.trace?.traceId,
|
||||
spans,
|
||||
truncated: spans.length >= MAX_TRACE_SPANS,
|
||||
};
|
||||
}
|
||||
|
||||
function curateErrors(data: unknown) {
|
||||
@@ -260,7 +264,13 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
if (!result.ok) return null;
|
||||
const d = result.data as Partial<RepoSnapshot> | undefined;
|
||||
if (!d?.tarballUrl || !d.owner || !d.repo || !d.sha) return null;
|
||||
return { tarballUrl: d.tarballUrl, owner: d.owner, repo: d.repo, sha: d.sha, defaultBranch: d.defaultBranch };
|
||||
return {
|
||||
tarballUrl: d.tarballUrl,
|
||||
owner: d.owner,
|
||||
repo: d.repo,
|
||||
sha: d.sha,
|
||||
defaultBranch: d.defaultBranch,
|
||||
};
|
||||
};
|
||||
|
||||
const apiTools: ToolSet = {
|
||||
@@ -280,7 +290,11 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
if (!hasAuth) return NO_AUTH;
|
||||
const ref = inputRef ?? projectRef;
|
||||
if (!ref) return { error: "No project ref available. Ask the user which project." };
|
||||
const result = await apiGet(origin, `/api/v1/projects/${ref}/environments`, userActorToken!);
|
||||
const result = await apiGet(
|
||||
origin,
|
||||
`/api/v1/projects/${ref}/environments`,
|
||||
userActorToken!
|
||||
);
|
||||
if (!result.ok) return { error: `Couldn't list environments (status ${result.status}).` };
|
||||
return curateEnvironments(result.data);
|
||||
},
|
||||
@@ -340,7 +354,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
const envJwt = await getEnvJwt();
|
||||
if (!envJwt) return { error: "No current environment is available to read runs from." };
|
||||
const result = await apiGet(origin, `/api/v1/runs/${runId}/trace`, envJwt);
|
||||
if (!result.ok) return { error: `Couldn't get the trace for ${runId} (status ${result.status}).` };
|
||||
if (!result.ok)
|
||||
return { error: `Couldn't get the trace for ${runId} (status ${result.status}).` };
|
||||
return curateTrace(result.data);
|
||||
},
|
||||
}),
|
||||
@@ -368,7 +383,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
const envJwt = await getEnvJwt();
|
||||
if (!envJwt) return { error: "No current environment is available to read errors from." };
|
||||
const result = await apiGet(origin, `/api/v1/errors/${errorId}`, envJwt);
|
||||
if (!result.ok) return { error: `Couldn't get error ${errorId} (status ${result.status}).` };
|
||||
if (!result.ok)
|
||||
return { error: `Couldn't get error ${errorId} (status ${result.status}).` };
|
||||
return curateError(result.data);
|
||||
},
|
||||
}),
|
||||
@@ -379,7 +395,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
const envJwt = await getEnvJwt();
|
||||
if (!envJwt) return { error: "No current environment is available to query." };
|
||||
const result = await apiGet(origin, "/api/v1/query/schema", envJwt);
|
||||
if (!result.ok) return { error: `Couldn't load the query schema (status ${result.status}).` };
|
||||
if (!result.ok)
|
||||
return { error: `Couldn't load the query schema (status ${result.status}).` };
|
||||
const tables = ((result.data as { tables?: any[] })?.tables ?? []) as any[];
|
||||
// No table → list what's queryable; a table → its columns.
|
||||
if (!table) {
|
||||
@@ -393,7 +410,9 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
}
|
||||
const match = tables.find((t) => t.name === table);
|
||||
if (!match) {
|
||||
return { error: `Unknown table "${table}". Available: ${tables.map((t) => t.name).join(", ")}.` };
|
||||
return {
|
||||
error: `Unknown table "${table}". Available: ${tables.map((t) => t.name).join(", ")}.`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
name: match.name,
|
||||
@@ -433,7 +452,9 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
// the model can fix the query rather than the turn dying.
|
||||
const data = (await res.json().catch(() => ({}))) as { results?: unknown; error?: string };
|
||||
if (!res.ok) return { error: data.error ?? `Query failed (status ${res.status}).` };
|
||||
const rows = Array.isArray(data.results) ? (data.results as Array<Record<string, unknown>>) : [];
|
||||
const rows = Array.isArray(data.results)
|
||||
? (data.results as Array<Record<string, unknown>>)
|
||||
: [];
|
||||
const cap = 200;
|
||||
return { rows: rows.slice(0, cap), rowCount: rows.length, truncated: rows.length > cap };
|
||||
},
|
||||
@@ -448,7 +469,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
execute: async ({ question }) => {
|
||||
const url = process.env.SUPPORT_ASK_URL ?? "http://localhost:3939/api/ask";
|
||||
const secret = process.env.SUPPORT_ASK_SECRET;
|
||||
if (!secret) return { error: "The support assistant isn't configured in this environment." };
|
||||
if (!secret)
|
||||
return { error: "The support assistant isn't configured in this environment." };
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 60_000);
|
||||
try {
|
||||
@@ -461,7 +483,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
}),
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!res.ok) return { error: `The support assistant request failed (status ${res.status}).` };
|
||||
if (!res.ok)
|
||||
return { error: `The support assistant request failed (status ${res.status}).` };
|
||||
// The endpoint streams a UI-message SSE; accumulate the text-delta
|
||||
// chunks into the final answer (tool-output-error chunks are noise).
|
||||
const body = await res.text();
|
||||
@@ -472,7 +495,8 @@ export function buildDashboardAgentTools(ctx: DashboardAgentToolContext): ToolSe
|
||||
if (!payload || payload === "[DONE]") continue;
|
||||
try {
|
||||
const chunk = JSON.parse(payload) as { type?: string; delta?: string };
|
||||
if (chunk.type === "text-delta" && typeof chunk.delta === "string") answer += chunk.delta;
|
||||
if (chunk.type === "text-delta" && typeof chunk.delta === "string")
|
||||
answer += chunk.delta;
|
||||
} catch {
|
||||
// Skip keepalives / non-JSON lines.
|
||||
}
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
"build": "pnpm run clean && tsc --noEmit false --outDir dist --declaration",
|
||||
"dev": "tsc --noEmit false --outDir dist --declaration --watch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ export default function Email(props: MfaEnabledEmailProps) {
|
||||
</Text>
|
||||
<Text style={paragraphLight}>
|
||||
• Keep your authenticator app safe and secured
|
||||
<br />
|
||||
• Never share your MFA codes with anyone
|
||||
<br />• Never share your MFA codes with anyone
|
||||
<br />• Store your recovery codes in a secure location
|
||||
</Text>
|
||||
<Text
|
||||
|
||||
@@ -2,9 +2,7 @@ import { ReactElement } from "react";
|
||||
|
||||
import { z } from "zod";
|
||||
import AlertAttemptFailureEmail, { AlertAttemptEmailSchema } from "../emails/alert-attempt-failure";
|
||||
import AlertErrorGroupEmail, {
|
||||
AlertErrorGroupEmailSchema,
|
||||
} from "../emails/alert-error-group";
|
||||
import AlertErrorGroupEmail, { AlertErrorGroupEmailSchema } from "../emails/alert-error-group";
|
||||
import AlertRunFailureEmail, { AlertRunEmailSchema } from "../emails/alert-run-failure";
|
||||
import { setGlobalBasePath } from "../emails/components/BasePath";
|
||||
import AlertDeploymentFailureEmail, {
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import { render } from "@react-email/render";
|
||||
import { EmailError, MailMessage, MailTransport, PlainTextMailMessage } from "./index";
|
||||
import nodemailer from "nodemailer"
|
||||
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2"
|
||||
import nodemailer from "nodemailer";
|
||||
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2";
|
||||
|
||||
export type AwsSesMailTransportOptions = {
|
||||
type: 'aws-ses',
|
||||
}
|
||||
type: "aws-ses";
|
||||
};
|
||||
|
||||
export class AwsSesMailTransport implements MailTransport {
|
||||
#client: nodemailer.Transporter;
|
||||
|
||||
constructor(options: AwsSesMailTransportOptions) {
|
||||
const sesClient = new SESv2Client()
|
||||
const sesClient = new SESv2Client();
|
||||
|
||||
this.#client = nodemailer.createTransport({
|
||||
SES: { sesClient, SendEmailCommand }
|
||||
})
|
||||
SES: { sesClient, SendEmailCommand },
|
||||
});
|
||||
}
|
||||
|
||||
async send({to, from, replyTo, subject, react}: MailMessage): Promise<void> {
|
||||
async send({ to, from, replyTo, subject, react }: MailMessage): Promise<void> {
|
||||
try {
|
||||
await this.#client.sendMail({
|
||||
from: from,
|
||||
@@ -27,8 +27,7 @@ export class AwsSesMailTransport implements MailTransport {
|
||||
subject,
|
||||
html: await render(react),
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error(
|
||||
`Failed to send email to ${to}, ${subject}. Error ${error.name}: ${error.message}`
|
||||
@@ -40,7 +39,7 @@ export class AwsSesMailTransport implements MailTransport {
|
||||
}
|
||||
}
|
||||
|
||||
async sendPlainText({to, from, replyTo, subject, text}: PlainTextMailMessage): Promise<void> {
|
||||
async sendPlainText({ to, from, replyTo, subject, text }: PlainTextMailMessage): Promise<void> {
|
||||
try {
|
||||
await this.#client.sendMail({
|
||||
from: from,
|
||||
@@ -49,8 +48,7 @@ export class AwsSesMailTransport implements MailTransport {
|
||||
subject,
|
||||
text: text,
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error(
|
||||
`Failed to send email to ${to}, ${subject}. Error ${error.name}: ${error.message}`
|
||||
|
||||
@@ -18,7 +18,7 @@ export type PlainTextMailMessage = {
|
||||
replyTo: string;
|
||||
subject: string;
|
||||
text: string;
|
||||
}
|
||||
};
|
||||
|
||||
export interface MailTransport {
|
||||
send(message: MailMessage): Promise<void>;
|
||||
@@ -33,13 +33,13 @@ export class EmailError extends Error {
|
||||
}
|
||||
|
||||
export type MailTransportOptions =
|
||||
AwsSesMailTransportOptions |
|
||||
ResendMailTransportOptions |
|
||||
NullMailTransportOptions |
|
||||
SmtpMailTransportOptions
|
||||
| AwsSesMailTransportOptions
|
||||
| ResendMailTransportOptions
|
||||
| NullMailTransportOptions
|
||||
| SmtpMailTransportOptions;
|
||||
|
||||
export function constructMailTransport(options: MailTransportOptions): MailTransport {
|
||||
switch(options.type) {
|
||||
switch (options.type) {
|
||||
case "aws-ses":
|
||||
return new AwsSesMailTransport(options);
|
||||
case "resend":
|
||||
|
||||
@@ -2,14 +2,13 @@ import { render } from "@react-email/render";
|
||||
import { MailMessage, MailTransport, PlainTextMailMessage } from "./index";
|
||||
|
||||
export type NullMailTransportOptions = {
|
||||
type: undefined,
|
||||
}
|
||||
type: undefined;
|
||||
};
|
||||
|
||||
export class NullMailTransport implements MailTransport {
|
||||
constructor(options: NullMailTransportOptions) {
|
||||
}
|
||||
constructor(options: NullMailTransportOptions) {}
|
||||
|
||||
async send({to, subject, react}: MailMessage): Promise<void> {
|
||||
async send({ to, subject, react }: MailMessage): Promise<void> {
|
||||
const plainText = await render(react, {
|
||||
plainText: true,
|
||||
});
|
||||
@@ -21,7 +20,7 @@ ${plainText}
|
||||
`);
|
||||
}
|
||||
|
||||
async sendPlainText({to, subject, text}: PlainTextMailMessage): Promise<void> {
|
||||
async sendPlainText({ to, subject, text }: PlainTextMailMessage): Promise<void> {
|
||||
console.log(`
|
||||
##### sendEmail to ${to}, subject: ${subject}
|
||||
|
||||
|
||||
@@ -2,20 +2,20 @@ import { EmailError, MailMessage, MailTransport, PlainTextMailMessage } from "./
|
||||
import { Resend } from "resend";
|
||||
|
||||
export type ResendMailTransportOptions = {
|
||||
type: 'resend',
|
||||
type: "resend";
|
||||
config: {
|
||||
apiKey?: string
|
||||
}
|
||||
}
|
||||
apiKey?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export class ResendMailTransport implements MailTransport {
|
||||
#client: Resend;
|
||||
|
||||
constructor(options: ResendMailTransportOptions) {
|
||||
this.#client = new Resend(options.config.apiKey)
|
||||
this.#client = new Resend(options.config.apiKey);
|
||||
}
|
||||
|
||||
async send({to, from, replyTo, subject, react}: MailMessage): Promise<void> {
|
||||
async send({ to, from, replyTo, subject, react }: MailMessage): Promise<void> {
|
||||
const result = await this.#client.emails.send({
|
||||
from: from,
|
||||
to,
|
||||
@@ -32,7 +32,7 @@ export class ResendMailTransport implements MailTransport {
|
||||
}
|
||||
}
|
||||
|
||||
async sendPlainText({to, from, replyTo, subject, text}: PlainTextMailMessage): Promise<void> {
|
||||
async sendPlainText({ to, from, replyTo, subject, text }: PlainTextMailMessage): Promise<void> {
|
||||
const result = await this.#client.emails.send({
|
||||
from: from,
|
||||
to,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"target": "ES2015",
|
||||
"target": "ES2015"
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -43,7 +43,8 @@ if (existsSync(pricesJsonPath)) {
|
||||
|
||||
let out = 'import type { DefaultModelDefinition } from "./types.js";\n\n';
|
||||
out += "// Auto-generated from default-model-prices.json — do not edit manually.\n";
|
||||
out += "// Run `pnpm run sync-prices` to update the JSON, then `pnpm run generate` to regenerate.\n";
|
||||
out +=
|
||||
"// Run `pnpm run sync-prices` to update the JSON, then `pnpm run generate` to regenerate.\n";
|
||||
out += "// Source: https://github.com/langfuse/langfuse\n\n";
|
||||
out += "export const defaultModelPrices: DefaultModelDefinition[] = ";
|
||||
out += JSON.stringify(stripped, null, 2) + ";\n";
|
||||
@@ -65,9 +66,12 @@ if (existsSync(catalogJsonPath)) {
|
||||
for (const key of Object.keys(data)) {
|
||||
if (data[key].releaseDate === undefined) data[key].releaseDate = null;
|
||||
if (data[key].isHidden === undefined) data[key].isHidden = false;
|
||||
if (data[key].supportsStructuredOutput === undefined) data[key].supportsStructuredOutput = false;
|
||||
if (data[key].supportsParallelToolCalls === undefined) data[key].supportsParallelToolCalls = false;
|
||||
if (data[key].supportsStreamingToolCalls === undefined) data[key].supportsStreamingToolCalls = false;
|
||||
if (data[key].supportsStructuredOutput === undefined)
|
||||
data[key].supportsStructuredOutput = false;
|
||||
if (data[key].supportsParallelToolCalls === undefined)
|
||||
data[key].supportsParallelToolCalls = false;
|
||||
if (data[key].supportsStreamingToolCalls === undefined)
|
||||
data[key].supportsStreamingToolCalls = false;
|
||||
if (data[key].deprecationDate === undefined) data[key].deprecationDate = null;
|
||||
if (data[key].knowledgeCutoff === undefined) data[key].knowledgeCutoff = null;
|
||||
if (data[key].resolvedAt === undefined) data[key].resolvedAt = new Date().toISOString();
|
||||
@@ -82,7 +86,8 @@ if (existsSync(catalogJsonPath)) {
|
||||
|
||||
let out = 'import type { ModelCatalogEntry } from "./types.js";\n\n';
|
||||
out += "// Auto-generated from model-catalog.json — do not edit manually.\n";
|
||||
out += "// Run `pnpm run generate-catalog` to update the JSON, then `pnpm run generate` to regenerate.\n\n";
|
||||
out +=
|
||||
"// Run `pnpm run generate-catalog` to update the JSON, then `pnpm run generate` to regenerate.\n\n";
|
||||
out += "export const modelCatalog: Record<string, ModelCatalogEntry> = ";
|
||||
out += JSON.stringify(data, null, 2) + ";\n";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -303,9 +303,7 @@ describe("ModelPricingRegistry", () => {
|
||||
name: "Large Context",
|
||||
isDefault: false,
|
||||
priority: 0,
|
||||
conditions: [
|
||||
{ usageDetailPattern: "input", operator: "gt" as const, value: 200000 },
|
||||
],
|
||||
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 200000 }],
|
||||
prices: [
|
||||
{ usageType: "input", price: 0.0000025 },
|
||||
{ usageType: "output", price: 0.00001 },
|
||||
@@ -371,9 +369,7 @@ describe("ModelPricingRegistry", () => {
|
||||
name: "Conditional",
|
||||
isDefault: false,
|
||||
priority: 1,
|
||||
conditions: [
|
||||
{ usageDetailPattern: "input", operator: "gt" as const, value: 100 },
|
||||
],
|
||||
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 100 }],
|
||||
prices: [{ usageType: "input", price: 0.0001 }],
|
||||
},
|
||||
{
|
||||
@@ -405,9 +401,7 @@ describe("ModelPricingRegistry", () => {
|
||||
name: "Conditional",
|
||||
isDefault: false,
|
||||
priority: 0,
|
||||
conditions: [
|
||||
{ usageDetailPattern: "input", operator: "gt" as const, value: 999999 },
|
||||
],
|
||||
conditions: [{ usageDetailPattern: "input", operator: "gt" as const, value: 999999 }],
|
||||
prices: [{ usageType: "input", price: 0.001 }],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -134,10 +134,7 @@ export class ModelPricingRegistry {
|
||||
return null;
|
||||
}
|
||||
|
||||
calculateCost(
|
||||
responseModel: string,
|
||||
usageDetails: Record<string, number>
|
||||
): LlmCostResult | null {
|
||||
calculateCost(responseModel: string, usageDetails: Record<string, number>): LlmCostResult | null {
|
||||
const model = this.match(responseModel);
|
||||
if (!model) return null;
|
||||
|
||||
|
||||
@@ -32,10 +32,7 @@ const STALE_BASE_MODEL_NAME = "wrong-base-model-sentinel";
|
||||
const STALE_INPUT_PRICE = 0.099;
|
||||
const STALE_OUTPUT_PRICE = 0.088;
|
||||
|
||||
async function createGpt4oWithStalePricing(
|
||||
prisma: PrismaClient,
|
||||
source: "default" | "admin"
|
||||
) {
|
||||
async function createGpt4oWithStalePricing(prisma: PrismaClient, source: "default" | "admin") {
|
||||
const model = await prisma.llmModel.create({
|
||||
data: {
|
||||
friendlyId: generateFriendlyId("llm_model"),
|
||||
@@ -129,7 +126,9 @@ async function loadGpt4oWithTiers(prisma: PrismaClient) {
|
||||
});
|
||||
}
|
||||
|
||||
function expectBundledGpt4oPricing(model: NonNullable<Awaited<ReturnType<typeof loadGpt4oWithTiers>>>) {
|
||||
function expectBundledGpt4oPricing(
|
||||
model: NonNullable<Awaited<ReturnType<typeof loadGpt4oWithTiers>>>
|
||||
) {
|
||||
expect(model.matchPattern).toBe(gpt4oDef.matchPattern);
|
||||
expect(model.pricingTiers).toHaveLength(gpt4oDef.pricingTiers.length);
|
||||
|
||||
|
||||
@@ -71,9 +71,7 @@ export async function syncLlmCatalog(prisma: PrismaClient): Promise<{
|
||||
capabilities: catalog?.capabilities ?? existing.capabilities,
|
||||
isHidden: catalog?.isHidden ?? existing.isHidden,
|
||||
baseModelName:
|
||||
catalog?.baseModelName === undefined
|
||||
? existing.baseModelName
|
||||
: catalog.baseModelName,
|
||||
catalog?.baseModelName === undefined ? existing.baseModelName : catalog.baseModelName,
|
||||
pricingUnit: existing.pricingUnit ?? "tokens",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
"long": "^5.2.3",
|
||||
"protobufjs": "^7.2.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+39
-17
@@ -108,10 +108,14 @@ export const ExportLogsServiceRequest = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(base?: I): ExportLogsServiceRequest {
|
||||
create<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(
|
||||
base?: I
|
||||
): ExportLogsServiceRequest {
|
||||
return ExportLogsServiceRequest.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(object: I): ExportLogsServiceRequest {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceRequest>, I>>(
|
||||
object: I
|
||||
): ExportLogsServiceRequest {
|
||||
const message = createBaseExportLogsServiceRequest();
|
||||
message.resourceLogs = object.resourceLogs?.map((e) => ResourceLogs.fromPartial(e)) || [];
|
||||
return message;
|
||||
@@ -169,14 +173,19 @@ export const ExportLogsServiceResponse = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(base?: I): ExportLogsServiceResponse {
|
||||
create<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(
|
||||
base?: I
|
||||
): ExportLogsServiceResponse {
|
||||
return ExportLogsServiceResponse.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(object: I): ExportLogsServiceResponse {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsServiceResponse>, I>>(
|
||||
object: I
|
||||
): ExportLogsServiceResponse {
|
||||
const message = createBaseExportLogsServiceResponse();
|
||||
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
|
||||
? ExportLogsPartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
message.partialSuccess =
|
||||
object.partialSuccess !== undefined && object.partialSuccess !== null
|
||||
? ExportLogsPartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -189,7 +198,9 @@ export const ExportLogsPartialSuccess = {
|
||||
encode(message: ExportLogsPartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.rejectedLogRecords !== BigInt("0")) {
|
||||
if (BigInt.asIntN(64, message.rejectedLogRecords) !== message.rejectedLogRecords) {
|
||||
throw new globalThis.Error("value provided for field message.rejectedLogRecords of type int64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.rejectedLogRecords of type int64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(8).int64(message.rejectedLogRecords.toString());
|
||||
}
|
||||
@@ -231,7 +242,9 @@ export const ExportLogsPartialSuccess = {
|
||||
|
||||
fromJSON(object: any): ExportLogsPartialSuccess {
|
||||
return {
|
||||
rejectedLogRecords: isSet(object.rejectedLogRecords) ? BigInt(object.rejectedLogRecords) : BigInt("0"),
|
||||
rejectedLogRecords: isSet(object.rejectedLogRecords)
|
||||
? BigInt(object.rejectedLogRecords)
|
||||
: BigInt("0"),
|
||||
errorMessage: isSet(object.errorMessage) ? globalThis.String(object.errorMessage) : "",
|
||||
};
|
||||
},
|
||||
@@ -247,10 +260,14 @@ export const ExportLogsPartialSuccess = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(base?: I): ExportLogsPartialSuccess {
|
||||
create<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(
|
||||
base?: I
|
||||
): ExportLogsPartialSuccess {
|
||||
return ExportLogsPartialSuccess.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(object: I): ExportLogsPartialSuccess {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportLogsPartialSuccess>, I>>(
|
||||
object: I
|
||||
): ExportLogsPartialSuccess {
|
||||
const message = createBaseExportLogsPartialSuccess();
|
||||
message.rejectedLogRecords = object.rejectedLogRecords ?? BigInt("0");
|
||||
message.errorMessage = object.errorMessage ?? "";
|
||||
@@ -293,14 +310,19 @@ interface Rpc {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
+53
-21
@@ -62,7 +62,10 @@ function createBaseExportMetricsServiceRequest(): ExportMetricsServiceRequest {
|
||||
}
|
||||
|
||||
export const ExportMetricsServiceRequest = {
|
||||
encode(message: ExportMetricsServiceRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExportMetricsServiceRequest,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
for (const v of message.resourceMetrics) {
|
||||
ResourceMetrics.encode(v!, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
@@ -108,12 +111,17 @@ export const ExportMetricsServiceRequest = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(base?: I): ExportMetricsServiceRequest {
|
||||
create<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(
|
||||
base?: I
|
||||
): ExportMetricsServiceRequest {
|
||||
return ExportMetricsServiceRequest.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(object: I): ExportMetricsServiceRequest {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceRequest>, I>>(
|
||||
object: I
|
||||
): ExportMetricsServiceRequest {
|
||||
const message = createBaseExportMetricsServiceRequest();
|
||||
message.resourceMetrics = object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
|
||||
message.resourceMetrics =
|
||||
object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -123,7 +131,10 @@ function createBaseExportMetricsServiceResponse(): ExportMetricsServiceResponse
|
||||
}
|
||||
|
||||
export const ExportMetricsServiceResponse = {
|
||||
encode(message: ExportMetricsServiceResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExportMetricsServiceResponse,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
if (message.partialSuccess !== undefined) {
|
||||
ExportMetricsPartialSuccess.encode(message.partialSuccess, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
@@ -169,14 +180,19 @@ export const ExportMetricsServiceResponse = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(base?: I): ExportMetricsServiceResponse {
|
||||
create<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(
|
||||
base?: I
|
||||
): ExportMetricsServiceResponse {
|
||||
return ExportMetricsServiceResponse.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(object: I): ExportMetricsServiceResponse {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsServiceResponse>, I>>(
|
||||
object: I
|
||||
): ExportMetricsServiceResponse {
|
||||
const message = createBaseExportMetricsServiceResponse();
|
||||
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
|
||||
? ExportMetricsPartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
message.partialSuccess =
|
||||
object.partialSuccess !== undefined && object.partialSuccess !== null
|
||||
? ExportMetricsPartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -186,10 +202,15 @@ function createBaseExportMetricsPartialSuccess(): ExportMetricsPartialSuccess {
|
||||
}
|
||||
|
||||
export const ExportMetricsPartialSuccess = {
|
||||
encode(message: ExportMetricsPartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExportMetricsPartialSuccess,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
if (message.rejectedDataPoints !== BigInt("0")) {
|
||||
if (BigInt.asIntN(64, message.rejectedDataPoints) !== message.rejectedDataPoints) {
|
||||
throw new globalThis.Error("value provided for field message.rejectedDataPoints of type int64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.rejectedDataPoints of type int64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(8).int64(message.rejectedDataPoints.toString());
|
||||
}
|
||||
@@ -231,7 +252,9 @@ export const ExportMetricsPartialSuccess = {
|
||||
|
||||
fromJSON(object: any): ExportMetricsPartialSuccess {
|
||||
return {
|
||||
rejectedDataPoints: isSet(object.rejectedDataPoints) ? BigInt(object.rejectedDataPoints) : BigInt("0"),
|
||||
rejectedDataPoints: isSet(object.rejectedDataPoints)
|
||||
? BigInt(object.rejectedDataPoints)
|
||||
: BigInt("0"),
|
||||
errorMessage: isSet(object.errorMessage) ? globalThis.String(object.errorMessage) : "",
|
||||
};
|
||||
},
|
||||
@@ -247,10 +270,14 @@ export const ExportMetricsPartialSuccess = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(base?: I): ExportMetricsPartialSuccess {
|
||||
create<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(
|
||||
base?: I
|
||||
): ExportMetricsPartialSuccess {
|
||||
return ExportMetricsPartialSuccess.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(object: I): ExportMetricsPartialSuccess {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportMetricsPartialSuccess>, I>>(
|
||||
object: I
|
||||
): ExportMetricsPartialSuccess {
|
||||
const message = createBaseExportMetricsPartialSuccess();
|
||||
message.rejectedDataPoints = object.rejectedDataPoints ?? BigInt("0");
|
||||
message.errorMessage = object.errorMessage ?? "";
|
||||
@@ -293,14 +320,19 @@ interface Rpc {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
+40
-17
@@ -108,10 +108,14 @@ export const ExportTraceServiceRequest = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(base?: I): ExportTraceServiceRequest {
|
||||
create<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(
|
||||
base?: I
|
||||
): ExportTraceServiceRequest {
|
||||
return ExportTraceServiceRequest.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(object: I): ExportTraceServiceRequest {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceRequest>, I>>(
|
||||
object: I
|
||||
): ExportTraceServiceRequest {
|
||||
const message = createBaseExportTraceServiceRequest();
|
||||
message.resourceSpans = object.resourceSpans?.map((e) => ResourceSpans.fromPartial(e)) || [];
|
||||
return message;
|
||||
@@ -123,7 +127,10 @@ function createBaseExportTraceServiceResponse(): ExportTraceServiceResponse {
|
||||
}
|
||||
|
||||
export const ExportTraceServiceResponse = {
|
||||
encode(message: ExportTraceServiceResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExportTraceServiceResponse,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
if (message.partialSuccess !== undefined) {
|
||||
ExportTracePartialSuccess.encode(message.partialSuccess, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
@@ -169,14 +176,19 @@ export const ExportTraceServiceResponse = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(base?: I): ExportTraceServiceResponse {
|
||||
create<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(
|
||||
base?: I
|
||||
): ExportTraceServiceResponse {
|
||||
return ExportTraceServiceResponse.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(object: I): ExportTraceServiceResponse {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTraceServiceResponse>, I>>(
|
||||
object: I
|
||||
): ExportTraceServiceResponse {
|
||||
const message = createBaseExportTraceServiceResponse();
|
||||
message.partialSuccess = (object.partialSuccess !== undefined && object.partialSuccess !== null)
|
||||
? ExportTracePartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
message.partialSuccess =
|
||||
object.partialSuccess !== undefined && object.partialSuccess !== null
|
||||
? ExportTracePartialSuccess.fromPartial(object.partialSuccess)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -189,7 +201,9 @@ export const ExportTracePartialSuccess = {
|
||||
encode(message: ExportTracePartialSuccess, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.rejectedSpans !== BigInt("0")) {
|
||||
if (BigInt.asIntN(64, message.rejectedSpans) !== message.rejectedSpans) {
|
||||
throw new globalThis.Error("value provided for field message.rejectedSpans of type int64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.rejectedSpans of type int64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(8).int64(message.rejectedSpans.toString());
|
||||
}
|
||||
@@ -247,10 +261,14 @@ export const ExportTracePartialSuccess = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(base?: I): ExportTracePartialSuccess {
|
||||
create<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(
|
||||
base?: I
|
||||
): ExportTracePartialSuccess {
|
||||
return ExportTracePartialSuccess.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(object: I): ExportTracePartialSuccess {
|
||||
fromPartial<I extends Exact<DeepPartial<ExportTracePartialSuccess>, I>>(
|
||||
object: I
|
||||
): ExportTracePartialSuccess {
|
||||
const message = createBaseExportTracePartialSuccess();
|
||||
message.rejectedSpans = object.rejectedSpans ?? BigInt("0");
|
||||
message.errorMessage = object.errorMessage ?? "";
|
||||
@@ -293,14 +311,19 @@ interface Rpc {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
+41
-21
@@ -93,7 +93,9 @@ export const AnyValue = {
|
||||
}
|
||||
if (message.intValue !== undefined) {
|
||||
if (BigInt.asIntN(64, message.intValue) !== message.intValue) {
|
||||
throw new globalThis.Error("value provided for field message.intValue of type int64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.intValue of type int64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(24).int64(message.intValue.toString());
|
||||
}
|
||||
@@ -184,8 +186,12 @@ export const AnyValue = {
|
||||
intValue: isSet(object.intValue) ? BigInt(object.intValue) : undefined,
|
||||
doubleValue: isSet(object.doubleValue) ? globalThis.Number(object.doubleValue) : undefined,
|
||||
arrayValue: isSet(object.arrayValue) ? ArrayValue.fromJSON(object.arrayValue) : undefined,
|
||||
kvlistValue: isSet(object.kvlistValue) ? KeyValueList.fromJSON(object.kvlistValue) : undefined,
|
||||
bytesValue: isSet(object.bytesValue) ? Buffer.from(bytesFromBase64(object.bytesValue)) : undefined,
|
||||
kvlistValue: isSet(object.kvlistValue)
|
||||
? KeyValueList.fromJSON(object.kvlistValue)
|
||||
: undefined,
|
||||
bytesValue: isSet(object.bytesValue)
|
||||
? Buffer.from(bytesFromBase64(object.bytesValue))
|
||||
: undefined,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -224,12 +230,14 @@ export const AnyValue = {
|
||||
message.boolValue = object.boolValue ?? undefined;
|
||||
message.intValue = object.intValue ?? undefined;
|
||||
message.doubleValue = object.doubleValue ?? undefined;
|
||||
message.arrayValue = (object.arrayValue !== undefined && object.arrayValue !== null)
|
||||
? ArrayValue.fromPartial(object.arrayValue)
|
||||
: undefined;
|
||||
message.kvlistValue = (object.kvlistValue !== undefined && object.kvlistValue !== null)
|
||||
? KeyValueList.fromPartial(object.kvlistValue)
|
||||
: undefined;
|
||||
message.arrayValue =
|
||||
object.arrayValue !== undefined && object.arrayValue !== null
|
||||
? ArrayValue.fromPartial(object.arrayValue)
|
||||
: undefined;
|
||||
message.kvlistValue =
|
||||
object.kvlistValue !== undefined && object.kvlistValue !== null
|
||||
? KeyValueList.fromPartial(object.kvlistValue)
|
||||
: undefined;
|
||||
message.bytesValue = object.bytesValue ?? undefined;
|
||||
return message;
|
||||
},
|
||||
@@ -272,7 +280,9 @@ export const ArrayValue = {
|
||||
|
||||
fromJSON(object: any): ArrayValue {
|
||||
return {
|
||||
values: globalThis.Array.isArray(object?.values) ? object.values.map((e: any) => AnyValue.fromJSON(e)) : [],
|
||||
values: globalThis.Array.isArray(object?.values)
|
||||
? object.values.map((e: any) => AnyValue.fromJSON(e))
|
||||
: [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -331,7 +341,9 @@ export const KeyValueList = {
|
||||
|
||||
fromJSON(object: any): KeyValueList {
|
||||
return {
|
||||
values: globalThis.Array.isArray(object?.values) ? object.values.map((e: any) => KeyValue.fromJSON(e)) : [],
|
||||
values: globalThis.Array.isArray(object?.values)
|
||||
? object.values.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -422,9 +434,10 @@ export const KeyValue = {
|
||||
fromPartial<I extends Exact<DeepPartial<KeyValue>, I>>(object: I): KeyValue {
|
||||
const message = createBaseKeyValue();
|
||||
message.key = object.key ?? "";
|
||||
message.value = (object.value !== undefined && object.value !== null)
|
||||
? AnyValue.fromPartial(object.value)
|
||||
: undefined;
|
||||
message.value =
|
||||
object.value !== undefined && object.value !== null
|
||||
? AnyValue.fromPartial(object.value)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -527,7 +540,9 @@ export const InstrumentationScope = {
|
||||
create<I extends Exact<DeepPartial<InstrumentationScope>, I>>(base?: I): InstrumentationScope {
|
||||
return InstrumentationScope.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<InstrumentationScope>, I>>(object: I): InstrumentationScope {
|
||||
fromPartial<I extends Exact<DeepPartial<InstrumentationScope>, I>>(
|
||||
object: I
|
||||
): InstrumentationScope {
|
||||
const message = createBaseInstrumentationScope();
|
||||
message.name = object.name ?? "";
|
||||
message.version = object.version ?? "";
|
||||
@@ -564,14 +579,19 @@ function base64FromBytes(arr: Uint8Array): string {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
@@ -255,9 +255,7 @@ export interface ResourceLogs {
|
||||
* The resource for the logs in this message.
|
||||
* If this field is not set then resource info is unknown.
|
||||
*/
|
||||
resource:
|
||||
| Resource
|
||||
| undefined;
|
||||
resource: Resource | undefined;
|
||||
/** A list of ScopeLogs that originate from a resource. */
|
||||
scopeLogs: ScopeLogs[];
|
||||
/**
|
||||
@@ -277,9 +275,7 @@ export interface ScopeLogs {
|
||||
* Semantically when InstrumentationScope isn't set, it is equivalent with
|
||||
* an empty instrumentation scope name (unknown).
|
||||
*/
|
||||
scope:
|
||||
| InstrumentationScope
|
||||
| undefined;
|
||||
scope: InstrumentationScope | undefined;
|
||||
/** A list of log records. */
|
||||
logRecords: LogRecord[];
|
||||
/**
|
||||
@@ -335,9 +331,7 @@ export interface LogRecord {
|
||||
* string message (including multi-line) describing the event in a free form or it can
|
||||
* be a structured data composed of arrays and maps of other values. [Optional].
|
||||
*/
|
||||
body:
|
||||
| AnyValue
|
||||
| undefined;
|
||||
body: AnyValue | undefined;
|
||||
/**
|
||||
* Additional attributes that describe the specific event occurrence. [Optional].
|
||||
* Attribute keys MUST be unique (it is not allowed to have more than one
|
||||
@@ -529,9 +523,10 @@ export const ResourceLogs = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ResourceLogs>, I>>(object: I): ResourceLogs {
|
||||
const message = createBaseResourceLogs();
|
||||
message.resource = (object.resource !== undefined && object.resource !== null)
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.resource =
|
||||
object.resource !== undefined && object.resource !== null
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.scopeLogs = object.scopeLogs?.map((e) => ScopeLogs.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -622,9 +617,10 @@ export const ScopeLogs = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ScopeLogs>, I>>(object: I): ScopeLogs {
|
||||
const message = createBaseScopeLogs();
|
||||
message.scope = (object.scope !== undefined && object.scope !== null)
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.scope =
|
||||
object.scope !== undefined && object.scope !== null
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.logRecords = object.logRecords?.map((e) => LogRecord.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -650,13 +646,17 @@ export const LogRecord = {
|
||||
encode(message: LogRecord, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(9).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
if (message.observedTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.observedTimeUnixNano) !== message.observedTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.observedTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.observedTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(89).fixed64(message.observedTimeUnixNano.toString());
|
||||
}
|
||||
@@ -776,8 +776,12 @@ export const LogRecord = {
|
||||
fromJSON(object: any): LogRecord {
|
||||
return {
|
||||
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
|
||||
observedTimeUnixNano: isSet(object.observedTimeUnixNano) ? BigInt(object.observedTimeUnixNano) : BigInt("0"),
|
||||
severityNumber: isSet(object.severityNumber) ? severityNumberFromJSON(object.severityNumber) : 0,
|
||||
observedTimeUnixNano: isSet(object.observedTimeUnixNano)
|
||||
? BigInt(object.observedTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
severityNumber: isSet(object.severityNumber)
|
||||
? severityNumberFromJSON(object.severityNumber)
|
||||
: 0,
|
||||
severityText: isSet(object.severityText) ? globalThis.String(object.severityText) : "",
|
||||
body: isSet(object.body) ? AnyValue.fromJSON(object.body) : undefined,
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
@@ -787,7 +791,9 @@ export const LogRecord = {
|
||||
? globalThis.Number(object.droppedAttributesCount)
|
||||
: 0,
|
||||
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
|
||||
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
|
||||
traceId: isSet(object.traceId)
|
||||
? Buffer.from(bytesFromBase64(object.traceId))
|
||||
: Buffer.alloc(0),
|
||||
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
|
||||
};
|
||||
},
|
||||
@@ -836,7 +842,10 @@ export const LogRecord = {
|
||||
message.observedTimeUnixNano = object.observedTimeUnixNano ?? BigInt("0");
|
||||
message.severityNumber = object.severityNumber ?? 0;
|
||||
message.severityText = object.severityText ?? "";
|
||||
message.body = (object.body !== undefined && object.body !== null) ? AnyValue.fromPartial(object.body) : undefined;
|
||||
message.body =
|
||||
object.body !== undefined && object.body !== null
|
||||
? AnyValue.fromPartial(object.body)
|
||||
: undefined;
|
||||
message.attributes = object.attributes?.map((e) => KeyValue.fromPartial(e)) || [];
|
||||
message.droppedAttributesCount = object.droppedAttributesCount ?? 0;
|
||||
message.flags = object.flags ?? 0;
|
||||
@@ -873,14 +882,19 @@ function base64FromBytes(arr: Uint8Array): string {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
+180
-109
@@ -193,9 +193,7 @@ export interface ResourceMetrics {
|
||||
* The resource for the metrics in this message.
|
||||
* If this field is not set then no resource info is known.
|
||||
*/
|
||||
resource:
|
||||
| Resource
|
||||
| undefined;
|
||||
resource: Resource | undefined;
|
||||
/** A list of metrics that originate from a resource. */
|
||||
scopeMetrics: ScopeMetrics[];
|
||||
/**
|
||||
@@ -215,9 +213,7 @@ export interface ScopeMetrics {
|
||||
* Semantically when InstrumentationScope isn't set, it is equivalent with
|
||||
* an empty instrumentation scope name (unknown).
|
||||
*/
|
||||
scope:
|
||||
| InstrumentationScope
|
||||
| undefined;
|
||||
scope: InstrumentationScope | undefined;
|
||||
/** A list of metrics that originate from an instrumentation library. */
|
||||
metrics: Metric[];
|
||||
/**
|
||||
@@ -329,9 +325,7 @@ export interface Metric {
|
||||
sum?: Sum | undefined;
|
||||
histogram?: Histogram | undefined;
|
||||
exponentialHistogram?: ExponentialHistogram | undefined;
|
||||
summary?:
|
||||
| Summary
|
||||
| undefined;
|
||||
summary?: Summary | undefined;
|
||||
/**
|
||||
* Additional metadata attributes that describe the metric. [Optional].
|
||||
* Attributes are non-identifying.
|
||||
@@ -440,9 +434,7 @@ export interface NumberDataPoint {
|
||||
*/
|
||||
timeUnixNano: bigint;
|
||||
asDouble?: number | undefined;
|
||||
asInt?:
|
||||
| bigint
|
||||
| undefined;
|
||||
asInt?: bigint | undefined;
|
||||
/**
|
||||
* (Optional) List of exemplars collected from
|
||||
* measurements that were used to form the data point
|
||||
@@ -506,9 +498,7 @@ export interface HistogramDataPoint {
|
||||
* doing so. This is specifically to enforce compatibility w/ OpenMetrics,
|
||||
* see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram
|
||||
*/
|
||||
sum?:
|
||||
| number
|
||||
| undefined;
|
||||
sum?: number | undefined;
|
||||
/**
|
||||
* bucket_counts is an optional field contains the count values of histogram
|
||||
* for each bucket.
|
||||
@@ -546,9 +536,7 @@ export interface HistogramDataPoint {
|
||||
*/
|
||||
flags: number;
|
||||
/** min is the minimum value over (start_time, end_time]. */
|
||||
min?:
|
||||
| number
|
||||
| undefined;
|
||||
min?: number | undefined;
|
||||
/** max is the maximum value over (start_time, end_time]. */
|
||||
max?: number | undefined;
|
||||
}
|
||||
@@ -598,9 +586,7 @@ export interface ExponentialHistogramDataPoint {
|
||||
* doing so. This is specifically to enforce compatibility w/ OpenMetrics,
|
||||
* see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram
|
||||
*/
|
||||
sum?:
|
||||
| number
|
||||
| undefined;
|
||||
sum?: number | undefined;
|
||||
/**
|
||||
* scale describes the resolution of the histogram. Boundaries are
|
||||
* located at powers of the base, where:
|
||||
@@ -631,13 +617,9 @@ export interface ExponentialHistogramDataPoint {
|
||||
*/
|
||||
zeroCount: bigint;
|
||||
/** positive carries the positive range of exponential bucket counts. */
|
||||
positive:
|
||||
| ExponentialHistogramDataPoint_Buckets
|
||||
| undefined;
|
||||
positive: ExponentialHistogramDataPoint_Buckets | undefined;
|
||||
/** negative carries the negative range of exponential bucket counts. */
|
||||
negative:
|
||||
| ExponentialHistogramDataPoint_Buckets
|
||||
| undefined;
|
||||
negative: ExponentialHistogramDataPoint_Buckets | undefined;
|
||||
/**
|
||||
* Flags that apply to this specific data point. See DataPointFlags
|
||||
* for the available flags and their meaning.
|
||||
@@ -649,13 +631,9 @@ export interface ExponentialHistogramDataPoint {
|
||||
*/
|
||||
exemplars: Exemplar[];
|
||||
/** min is the minimum value over (start_time, end_time]. */
|
||||
min?:
|
||||
| number
|
||||
| undefined;
|
||||
min?: number | undefined;
|
||||
/** max is the maximum value over (start_time, end_time]. */
|
||||
max?:
|
||||
| number
|
||||
| undefined;
|
||||
max?: number | undefined;
|
||||
/**
|
||||
* ZeroThreshold may be optionally set to convey the width of the zero
|
||||
* region. Where the zero region is defined as the closed interval
|
||||
@@ -789,9 +767,7 @@ export interface Exemplar {
|
||||
*/
|
||||
timeUnixNano: bigint;
|
||||
asDouble?: number | undefined;
|
||||
asInt?:
|
||||
| bigint
|
||||
| undefined;
|
||||
asInt?: bigint | undefined;
|
||||
/**
|
||||
* (Optional) Span ID of the exemplar trace.
|
||||
* span_id may be missing if the measurement is not recorded inside a trace
|
||||
@@ -862,7 +838,8 @@ export const MetricsData = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<MetricsData>, I>>(object: I): MetricsData {
|
||||
const message = createBaseMetricsData();
|
||||
message.resourceMetrics = object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
|
||||
message.resourceMetrics =
|
||||
object.resourceMetrics?.map((e) => ResourceMetrics.fromPartial(e)) || [];
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -951,9 +928,10 @@ export const ResourceMetrics = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ResourceMetrics>, I>>(object: I): ResourceMetrics {
|
||||
const message = createBaseResourceMetrics();
|
||||
message.resource = (object.resource !== undefined && object.resource !== null)
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.resource =
|
||||
object.resource !== undefined && object.resource !== null
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.scopeMetrics = object.scopeMetrics?.map((e) => ScopeMetrics.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -1018,7 +996,9 @@ export const ScopeMetrics = {
|
||||
fromJSON(object: any): ScopeMetrics {
|
||||
return {
|
||||
scope: isSet(object.scope) ? InstrumentationScope.fromJSON(object.scope) : undefined,
|
||||
metrics: globalThis.Array.isArray(object?.metrics) ? object.metrics.map((e: any) => Metric.fromJSON(e)) : [],
|
||||
metrics: globalThis.Array.isArray(object?.metrics)
|
||||
? object.metrics.map((e: any) => Metric.fromJSON(e))
|
||||
: [],
|
||||
schemaUrl: isSet(object.schemaUrl) ? globalThis.String(object.schemaUrl) : "",
|
||||
};
|
||||
},
|
||||
@@ -1042,9 +1022,10 @@ export const ScopeMetrics = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ScopeMetrics>, I>>(object: I): ScopeMetrics {
|
||||
const message = createBaseScopeMetrics();
|
||||
message.scope = (object.scope !== undefined && object.scope !== null)
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.scope =
|
||||
object.scope !== undefined && object.scope !== null
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.metrics = object.metrics?.map((e) => Metric.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -1188,7 +1169,9 @@ export const Metric = {
|
||||
? ExponentialHistogram.fromJSON(object.exponentialHistogram)
|
||||
: undefined,
|
||||
summary: isSet(object.summary) ? Summary.fromJSON(object.summary) : undefined,
|
||||
metadata: globalThis.Array.isArray(object?.metadata) ? object.metadata.map((e: any) => KeyValue.fromJSON(e)) : [],
|
||||
metadata: globalThis.Array.isArray(object?.metadata)
|
||||
? object.metadata.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1232,17 +1215,24 @@ export const Metric = {
|
||||
message.name = object.name ?? "";
|
||||
message.description = object.description ?? "";
|
||||
message.unit = object.unit ?? "";
|
||||
message.gauge = (object.gauge !== undefined && object.gauge !== null) ? Gauge.fromPartial(object.gauge) : undefined;
|
||||
message.sum = (object.sum !== undefined && object.sum !== null) ? Sum.fromPartial(object.sum) : undefined;
|
||||
message.histogram = (object.histogram !== undefined && object.histogram !== null)
|
||||
? Histogram.fromPartial(object.histogram)
|
||||
: undefined;
|
||||
message.exponentialHistogram = (object.exponentialHistogram !== undefined && object.exponentialHistogram !== null)
|
||||
? ExponentialHistogram.fromPartial(object.exponentialHistogram)
|
||||
: undefined;
|
||||
message.summary = (object.summary !== undefined && object.summary !== null)
|
||||
? Summary.fromPartial(object.summary)
|
||||
: undefined;
|
||||
message.gauge =
|
||||
object.gauge !== undefined && object.gauge !== null
|
||||
? Gauge.fromPartial(object.gauge)
|
||||
: undefined;
|
||||
message.sum =
|
||||
object.sum !== undefined && object.sum !== null ? Sum.fromPartial(object.sum) : undefined;
|
||||
message.histogram =
|
||||
object.histogram !== undefined && object.histogram !== null
|
||||
? Histogram.fromPartial(object.histogram)
|
||||
: undefined;
|
||||
message.exponentialHistogram =
|
||||
object.exponentialHistogram !== undefined && object.exponentialHistogram !== null
|
||||
? ExponentialHistogram.fromPartial(object.exponentialHistogram)
|
||||
: undefined;
|
||||
message.summary =
|
||||
object.summary !== undefined && object.summary !== null
|
||||
? Summary.fromPartial(object.summary)
|
||||
: undefined;
|
||||
message.metadata = object.metadata?.map((e) => KeyValue.fromPartial(e)) || [];
|
||||
return message;
|
||||
},
|
||||
@@ -1550,9 +1540,12 @@ export const ExponentialHistogram = {
|
||||
create<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(base?: I): ExponentialHistogram {
|
||||
return ExponentialHistogram.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(object: I): ExponentialHistogram {
|
||||
fromPartial<I extends Exact<DeepPartial<ExponentialHistogram>, I>>(
|
||||
object: I
|
||||
): ExponentialHistogram {
|
||||
const message = createBaseExponentialHistogram();
|
||||
message.dataPoints = object.dataPoints?.map((e) => ExponentialHistogramDataPoint.fromPartial(e)) || [];
|
||||
message.dataPoints =
|
||||
object.dataPoints?.map((e) => ExponentialHistogramDataPoint.fromPartial(e)) || [];
|
||||
message.aggregationTemporality = object.aggregationTemporality ?? 0;
|
||||
return message;
|
||||
},
|
||||
@@ -1638,13 +1631,17 @@ export const NumberDataPoint = {
|
||||
}
|
||||
if (message.startTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.startTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
|
||||
}
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(25).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
@@ -1653,7 +1650,9 @@ export const NumberDataPoint = {
|
||||
}
|
||||
if (message.asInt !== undefined) {
|
||||
if (BigInt.asIntN(64, message.asInt) !== message.asInt) {
|
||||
throw new globalThis.Error("value provided for field message.asInt of type sfixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.asInt of type sfixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(49).sfixed64(message.asInt.toString());
|
||||
}
|
||||
@@ -1736,7 +1735,9 @@ export const NumberDataPoint = {
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano)
|
||||
? BigInt(object.startTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
|
||||
asDouble: isSet(object.asDouble) ? globalThis.Number(object.asDouble) : undefined,
|
||||
asInt: isSet(object.asInt) ? BigInt(object.asInt) : undefined,
|
||||
@@ -1812,19 +1813,25 @@ export const HistogramDataPoint = {
|
||||
}
|
||||
if (message.startTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.startTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
|
||||
}
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(25).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
if (message.count !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.count) !== message.count) {
|
||||
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.count of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(33).fixed64(message.count.toString());
|
||||
}
|
||||
@@ -1834,7 +1841,9 @@ export const HistogramDataPoint = {
|
||||
writer.uint32(50).fork();
|
||||
for (const v of message.bucketCounts) {
|
||||
if (BigInt.asUintN(64, v) !== v) {
|
||||
throw new globalThis.Error("a value provided in array field bucketCounts of type fixed64 is too large");
|
||||
throw new globalThis.Error(
|
||||
"a value provided in array field bucketCounts of type fixed64 is too large"
|
||||
);
|
||||
}
|
||||
writer.fixed64(v.toString());
|
||||
}
|
||||
@@ -1977,7 +1986,9 @@ export const HistogramDataPoint = {
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano)
|
||||
? BigInt(object.startTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
|
||||
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
|
||||
sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined,
|
||||
@@ -2074,25 +2085,34 @@ function createBaseExponentialHistogramDataPoint(): ExponentialHistogramDataPoin
|
||||
}
|
||||
|
||||
export const ExponentialHistogramDataPoint = {
|
||||
encode(message: ExponentialHistogramDataPoint, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExponentialHistogramDataPoint,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
for (const v of message.attributes) {
|
||||
KeyValue.encode(v!, writer.uint32(10).fork()).ldelim();
|
||||
}
|
||||
if (message.startTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.startTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
|
||||
}
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(25).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
if (message.count !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.count) !== message.count) {
|
||||
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.count of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(33).fixed64(message.count.toString());
|
||||
}
|
||||
@@ -2104,15 +2124,23 @@ export const ExponentialHistogramDataPoint = {
|
||||
}
|
||||
if (message.zeroCount !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.zeroCount) !== message.zeroCount) {
|
||||
throw new globalThis.Error("value provided for field message.zeroCount of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.zeroCount of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(57).fixed64(message.zeroCount.toString());
|
||||
}
|
||||
if (message.positive !== undefined) {
|
||||
ExponentialHistogramDataPoint_Buckets.encode(message.positive, writer.uint32(66).fork()).ldelim();
|
||||
ExponentialHistogramDataPoint_Buckets.encode(
|
||||
message.positive,
|
||||
writer.uint32(66).fork()
|
||||
).ldelim();
|
||||
}
|
||||
if (message.negative !== undefined) {
|
||||
ExponentialHistogramDataPoint_Buckets.encode(message.negative, writer.uint32(74).fork()).ldelim();
|
||||
ExponentialHistogramDataPoint_Buckets.encode(
|
||||
message.negative,
|
||||
writer.uint32(74).fork()
|
||||
).ldelim();
|
||||
}
|
||||
if (message.flags !== 0) {
|
||||
writer.uint32(80).uint32(message.flags);
|
||||
@@ -2251,14 +2279,20 @@ export const ExponentialHistogramDataPoint = {
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano)
|
||||
? BigInt(object.startTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
|
||||
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
|
||||
sum: isSet(object.sum) ? globalThis.Number(object.sum) : undefined,
|
||||
scale: isSet(object.scale) ? globalThis.Number(object.scale) : 0,
|
||||
zeroCount: isSet(object.zeroCount) ? BigInt(object.zeroCount) : BigInt("0"),
|
||||
positive: isSet(object.positive) ? ExponentialHistogramDataPoint_Buckets.fromJSON(object.positive) : undefined,
|
||||
negative: isSet(object.negative) ? ExponentialHistogramDataPoint_Buckets.fromJSON(object.negative) : undefined,
|
||||
positive: isSet(object.positive)
|
||||
? ExponentialHistogramDataPoint_Buckets.fromJSON(object.positive)
|
||||
: undefined,
|
||||
negative: isSet(object.negative)
|
||||
? ExponentialHistogramDataPoint_Buckets.fromJSON(object.negative)
|
||||
: undefined,
|
||||
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
|
||||
exemplars: globalThis.Array.isArray(object?.exemplars)
|
||||
? object.exemplars.map((e: any) => Exemplar.fromJSON(e))
|
||||
@@ -2316,11 +2350,13 @@ export const ExponentialHistogramDataPoint = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(base?: I): ExponentialHistogramDataPoint {
|
||||
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(
|
||||
base?: I
|
||||
): ExponentialHistogramDataPoint {
|
||||
return ExponentialHistogramDataPoint.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExponentialHistogramDataPoint>, I>>(
|
||||
object: I,
|
||||
object: I
|
||||
): ExponentialHistogramDataPoint {
|
||||
const message = createBaseExponentialHistogramDataPoint();
|
||||
message.attributes = object.attributes?.map((e) => KeyValue.fromPartial(e)) || [];
|
||||
@@ -2330,12 +2366,14 @@ export const ExponentialHistogramDataPoint = {
|
||||
message.sum = object.sum ?? undefined;
|
||||
message.scale = object.scale ?? 0;
|
||||
message.zeroCount = object.zeroCount ?? BigInt("0");
|
||||
message.positive = (object.positive !== undefined && object.positive !== null)
|
||||
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.positive)
|
||||
: undefined;
|
||||
message.negative = (object.negative !== undefined && object.negative !== null)
|
||||
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.negative)
|
||||
: undefined;
|
||||
message.positive =
|
||||
object.positive !== undefined && object.positive !== null
|
||||
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.positive)
|
||||
: undefined;
|
||||
message.negative =
|
||||
object.negative !== undefined && object.negative !== null
|
||||
? ExponentialHistogramDataPoint_Buckets.fromPartial(object.negative)
|
||||
: undefined;
|
||||
message.flags = object.flags ?? 0;
|
||||
message.exemplars = object.exemplars?.map((e) => Exemplar.fromPartial(e)) || [];
|
||||
message.min = object.min ?? undefined;
|
||||
@@ -2350,14 +2388,19 @@ function createBaseExponentialHistogramDataPoint_Buckets(): ExponentialHistogram
|
||||
}
|
||||
|
||||
export const ExponentialHistogramDataPoint_Buckets = {
|
||||
encode(message: ExponentialHistogramDataPoint_Buckets, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: ExponentialHistogramDataPoint_Buckets,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
if (message.offset !== 0) {
|
||||
writer.uint32(8).sint32(message.offset);
|
||||
}
|
||||
writer.uint32(18).fork();
|
||||
for (const v of message.bucketCounts) {
|
||||
if (BigInt.asUintN(64, v) !== v) {
|
||||
throw new globalThis.Error("a value provided in array field bucketCounts of type uint64 is too large");
|
||||
throw new globalThis.Error(
|
||||
"a value provided in array field bucketCounts of type uint64 is too large"
|
||||
);
|
||||
}
|
||||
writer.uint64(v.toString());
|
||||
}
|
||||
@@ -2426,12 +2469,12 @@ export const ExponentialHistogramDataPoint_Buckets = {
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<ExponentialHistogramDataPoint_Buckets>, I>>(
|
||||
base?: I,
|
||||
base?: I
|
||||
): ExponentialHistogramDataPoint_Buckets {
|
||||
return ExponentialHistogramDataPoint_Buckets.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ExponentialHistogramDataPoint_Buckets>, I>>(
|
||||
object: I,
|
||||
object: I
|
||||
): ExponentialHistogramDataPoint_Buckets {
|
||||
const message = createBaseExponentialHistogramDataPoint_Buckets();
|
||||
message.offset = object.offset ?? 0;
|
||||
@@ -2459,19 +2502,25 @@ export const SummaryDataPoint = {
|
||||
}
|
||||
if (message.startTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.startTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(17).fixed64(message.startTimeUnixNano.toString());
|
||||
}
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(25).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
if (message.count !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.count) !== message.count) {
|
||||
throw new globalThis.Error("value provided for field message.count of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.count of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(33).fixed64(message.count.toString());
|
||||
}
|
||||
@@ -2534,7 +2583,9 @@ export const SummaryDataPoint = {
|
||||
break;
|
||||
}
|
||||
|
||||
message.quantileValues.push(SummaryDataPoint_ValueAtQuantile.decode(reader, reader.uint32()));
|
||||
message.quantileValues.push(
|
||||
SummaryDataPoint_ValueAtQuantile.decode(reader, reader.uint32())
|
||||
);
|
||||
continue;
|
||||
case 8:
|
||||
if (tag !== 64) {
|
||||
@@ -2557,7 +2608,9 @@ export const SummaryDataPoint = {
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
|
||||
: [],
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano)
|
||||
? BigInt(object.startTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
timeUnixNano: isSet(object.timeUnixNano) ? BigInt(object.timeUnixNano) : BigInt("0"),
|
||||
count: isSet(object.count) ? BigInt(object.count) : BigInt("0"),
|
||||
sum: isSet(object.sum) ? globalThis.Number(object.sum) : 0,
|
||||
@@ -2586,7 +2639,9 @@ export const SummaryDataPoint = {
|
||||
obj.sum = message.sum;
|
||||
}
|
||||
if (message.quantileValues?.length) {
|
||||
obj.quantileValues = message.quantileValues.map((e) => SummaryDataPoint_ValueAtQuantile.toJSON(e));
|
||||
obj.quantileValues = message.quantileValues.map((e) =>
|
||||
SummaryDataPoint_ValueAtQuantile.toJSON(e)
|
||||
);
|
||||
}
|
||||
if (message.flags !== 0) {
|
||||
obj.flags = Math.round(message.flags);
|
||||
@@ -2604,7 +2659,8 @@ export const SummaryDataPoint = {
|
||||
message.timeUnixNano = object.timeUnixNano ?? BigInt("0");
|
||||
message.count = object.count ?? BigInt("0");
|
||||
message.sum = object.sum ?? 0;
|
||||
message.quantileValues = object.quantileValues?.map((e) => SummaryDataPoint_ValueAtQuantile.fromPartial(e)) || [];
|
||||
message.quantileValues =
|
||||
object.quantileValues?.map((e) => SummaryDataPoint_ValueAtQuantile.fromPartial(e)) || [];
|
||||
message.flags = object.flags ?? 0;
|
||||
return message;
|
||||
},
|
||||
@@ -2615,7 +2671,10 @@ function createBaseSummaryDataPoint_ValueAtQuantile(): SummaryDataPoint_ValueAtQ
|
||||
}
|
||||
|
||||
export const SummaryDataPoint_ValueAtQuantile = {
|
||||
encode(message: SummaryDataPoint_ValueAtQuantile, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
encode(
|
||||
message: SummaryDataPoint_ValueAtQuantile,
|
||||
writer: _m0.Writer = _m0.Writer.create()
|
||||
): _m0.Writer {
|
||||
if (message.quantile !== 0) {
|
||||
writer.uint32(9).double(message.quantile);
|
||||
}
|
||||
@@ -2674,12 +2733,12 @@ export const SummaryDataPoint_ValueAtQuantile = {
|
||||
},
|
||||
|
||||
create<I extends Exact<DeepPartial<SummaryDataPoint_ValueAtQuantile>, I>>(
|
||||
base?: I,
|
||||
base?: I
|
||||
): SummaryDataPoint_ValueAtQuantile {
|
||||
return SummaryDataPoint_ValueAtQuantile.fromPartial(base ?? ({} as any));
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<SummaryDataPoint_ValueAtQuantile>, I>>(
|
||||
object: I,
|
||||
object: I
|
||||
): SummaryDataPoint_ValueAtQuantile {
|
||||
const message = createBaseSummaryDataPoint_ValueAtQuantile();
|
||||
message.quantile = object.quantile ?? 0;
|
||||
@@ -2706,7 +2765,9 @@ export const Exemplar = {
|
||||
}
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(17).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
@@ -2715,7 +2776,9 @@ export const Exemplar = {
|
||||
}
|
||||
if (message.asInt !== undefined) {
|
||||
if (BigInt.asIntN(64, message.asInt) !== message.asInt) {
|
||||
throw new globalThis.Error("value provided for field message.asInt of type sfixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.asInt of type sfixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(49).sfixed64(message.asInt.toString());
|
||||
}
|
||||
@@ -2795,7 +2858,9 @@ export const Exemplar = {
|
||||
asDouble: isSet(object.asDouble) ? globalThis.Number(object.asDouble) : undefined,
|
||||
asInt: isSet(object.asInt) ? BigInt(object.asInt) : undefined,
|
||||
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
|
||||
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
|
||||
traceId: isSet(object.traceId)
|
||||
? Buffer.from(bytesFromBase64(object.traceId))
|
||||
: Buffer.alloc(0),
|
||||
};
|
||||
},
|
||||
|
||||
@@ -2827,7 +2892,8 @@ export const Exemplar = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<Exemplar>, I>>(object: I): Exemplar {
|
||||
const message = createBaseExemplar();
|
||||
message.filteredAttributes = object.filteredAttributes?.map((e) => KeyValue.fromPartial(e)) || [];
|
||||
message.filteredAttributes =
|
||||
object.filteredAttributes?.map((e) => KeyValue.fromPartial(e)) || [];
|
||||
message.timeUnixNano = object.timeUnixNano ?? BigInt("0");
|
||||
message.asDouble = object.asDouble ?? undefined;
|
||||
message.asInt = object.asInt ?? undefined;
|
||||
@@ -2864,14 +2930,19 @@ function base64FromBytes(arr: Uint8Array): string {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
+11
-6
@@ -99,14 +99,19 @@ export const Resource = {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function isSet(value: any): boolean {
|
||||
|
||||
+61
-33
@@ -106,9 +106,7 @@ export interface ResourceSpans {
|
||||
* The resource for the spans in this message.
|
||||
* If this field is not set then no resource info is known.
|
||||
*/
|
||||
resource:
|
||||
| Resource
|
||||
| undefined;
|
||||
resource: Resource | undefined;
|
||||
/** A list of ScopeSpans that originate from a resource. */
|
||||
scopeSpans: ScopeSpans[];
|
||||
/**
|
||||
@@ -128,9 +126,7 @@ export interface ScopeSpans {
|
||||
* Semantically when InstrumentationScope isn't set, it is equivalent with
|
||||
* an empty instrumentation scope name (unknown).
|
||||
*/
|
||||
scope:
|
||||
| InstrumentationScope
|
||||
| undefined;
|
||||
scope: InstrumentationScope | undefined;
|
||||
/** A list of Spans that originate from an instrumentation scope. */
|
||||
spans: Span[];
|
||||
/**
|
||||
@@ -648,9 +644,10 @@ export const ResourceSpans = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ResourceSpans>, I>>(object: I): ResourceSpans {
|
||||
const message = createBaseResourceSpans();
|
||||
message.resource = (object.resource !== undefined && object.resource !== null)
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.resource =
|
||||
object.resource !== undefined && object.resource !== null
|
||||
? Resource.fromPartial(object.resource)
|
||||
: undefined;
|
||||
message.scopeSpans = object.scopeSpans?.map((e) => ScopeSpans.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -715,7 +712,9 @@ export const ScopeSpans = {
|
||||
fromJSON(object: any): ScopeSpans {
|
||||
return {
|
||||
scope: isSet(object.scope) ? InstrumentationScope.fromJSON(object.scope) : undefined,
|
||||
spans: globalThis.Array.isArray(object?.spans) ? object.spans.map((e: any) => Span.fromJSON(e)) : [],
|
||||
spans: globalThis.Array.isArray(object?.spans)
|
||||
? object.spans.map((e: any) => Span.fromJSON(e))
|
||||
: [],
|
||||
schemaUrl: isSet(object.schemaUrl) ? globalThis.String(object.schemaUrl) : "",
|
||||
};
|
||||
},
|
||||
@@ -739,9 +738,10 @@ export const ScopeSpans = {
|
||||
},
|
||||
fromPartial<I extends Exact<DeepPartial<ScopeSpans>, I>>(object: I): ScopeSpans {
|
||||
const message = createBaseScopeSpans();
|
||||
message.scope = (object.scope !== undefined && object.scope !== null)
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.scope =
|
||||
object.scope !== undefined && object.scope !== null
|
||||
? InstrumentationScope.fromPartial(object.scope)
|
||||
: undefined;
|
||||
message.spans = object.spans?.map((e) => Span.fromPartial(e)) || [];
|
||||
message.schemaUrl = object.schemaUrl ?? "";
|
||||
return message;
|
||||
@@ -794,13 +794,17 @@ export const Span = {
|
||||
}
|
||||
if (message.startTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.startTimeUnixNano) !== message.startTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.startTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.startTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(57).fixed64(message.startTimeUnixNano.toString());
|
||||
}
|
||||
if (message.endTimeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.endTimeUnixNano) !== message.endTimeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.endTimeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.endTimeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(65).fixed64(message.endTimeUnixNano.toString());
|
||||
}
|
||||
@@ -958,14 +962,20 @@ export const Span = {
|
||||
|
||||
fromJSON(object: any): Span {
|
||||
return {
|
||||
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
|
||||
traceId: isSet(object.traceId)
|
||||
? Buffer.from(bytesFromBase64(object.traceId))
|
||||
: Buffer.alloc(0),
|
||||
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
|
||||
traceState: isSet(object.traceState) ? globalThis.String(object.traceState) : "",
|
||||
parentSpanId: isSet(object.parentSpanId) ? Buffer.from(bytesFromBase64(object.parentSpanId)) : Buffer.alloc(0),
|
||||
parentSpanId: isSet(object.parentSpanId)
|
||||
? Buffer.from(bytesFromBase64(object.parentSpanId))
|
||||
: Buffer.alloc(0),
|
||||
flags: isSet(object.flags) ? globalThis.Number(object.flags) : 0,
|
||||
name: isSet(object.name) ? globalThis.String(object.name) : "",
|
||||
kind: isSet(object.kind) ? span_SpanKindFromJSON(object.kind) : 0,
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano) ? BigInt(object.startTimeUnixNano) : BigInt("0"),
|
||||
startTimeUnixNano: isSet(object.startTimeUnixNano)
|
||||
? BigInt(object.startTimeUnixNano)
|
||||
: BigInt("0"),
|
||||
endTimeUnixNano: isSet(object.endTimeUnixNano) ? BigInt(object.endTimeUnixNano) : BigInt("0"),
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
? object.attributes.map((e: any) => KeyValue.fromJSON(e))
|
||||
@@ -973,10 +983,18 @@ export const Span = {
|
||||
droppedAttributesCount: isSet(object.droppedAttributesCount)
|
||||
? globalThis.Number(object.droppedAttributesCount)
|
||||
: 0,
|
||||
events: globalThis.Array.isArray(object?.events) ? object.events.map((e: any) => Span_Event.fromJSON(e)) : [],
|
||||
droppedEventsCount: isSet(object.droppedEventsCount) ? globalThis.Number(object.droppedEventsCount) : 0,
|
||||
links: globalThis.Array.isArray(object?.links) ? object.links.map((e: any) => Span_Link.fromJSON(e)) : [],
|
||||
droppedLinksCount: isSet(object.droppedLinksCount) ? globalThis.Number(object.droppedLinksCount) : 0,
|
||||
events: globalThis.Array.isArray(object?.events)
|
||||
? object.events.map((e: any) => Span_Event.fromJSON(e))
|
||||
: [],
|
||||
droppedEventsCount: isSet(object.droppedEventsCount)
|
||||
? globalThis.Number(object.droppedEventsCount)
|
||||
: 0,
|
||||
links: globalThis.Array.isArray(object?.links)
|
||||
? object.links.map((e: any) => Span_Link.fromJSON(e))
|
||||
: [],
|
||||
droppedLinksCount: isSet(object.droppedLinksCount)
|
||||
? globalThis.Number(object.droppedLinksCount)
|
||||
: 0,
|
||||
status: isSet(object.status) ? Status.fromJSON(object.status) : undefined,
|
||||
};
|
||||
},
|
||||
@@ -1054,9 +1072,10 @@ export const Span = {
|
||||
message.droppedEventsCount = object.droppedEventsCount ?? 0;
|
||||
message.links = object.links?.map((e) => Span_Link.fromPartial(e)) || [];
|
||||
message.droppedLinksCount = object.droppedLinksCount ?? 0;
|
||||
message.status = (object.status !== undefined && object.status !== null)
|
||||
? Status.fromPartial(object.status)
|
||||
: undefined;
|
||||
message.status =
|
||||
object.status !== undefined && object.status !== null
|
||||
? Status.fromPartial(object.status)
|
||||
: undefined;
|
||||
return message;
|
||||
},
|
||||
};
|
||||
@@ -1069,7 +1088,9 @@ export const Span_Event = {
|
||||
encode(message: Span_Event, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
|
||||
if (message.timeUnixNano !== BigInt("0")) {
|
||||
if (BigInt.asUintN(64, message.timeUnixNano) !== message.timeUnixNano) {
|
||||
throw new globalThis.Error("value provided for field message.timeUnixNano of type fixed64 too large");
|
||||
throw new globalThis.Error(
|
||||
"value provided for field message.timeUnixNano of type fixed64 too large"
|
||||
);
|
||||
}
|
||||
writer.uint32(9).fixed64(message.timeUnixNano.toString());
|
||||
}
|
||||
@@ -1266,7 +1287,9 @@ export const Span_Link = {
|
||||
|
||||
fromJSON(object: any): Span_Link {
|
||||
return {
|
||||
traceId: isSet(object.traceId) ? Buffer.from(bytesFromBase64(object.traceId)) : Buffer.alloc(0),
|
||||
traceId: isSet(object.traceId)
|
||||
? Buffer.from(bytesFromBase64(object.traceId))
|
||||
: Buffer.alloc(0),
|
||||
spanId: isSet(object.spanId) ? Buffer.from(bytesFromBase64(object.spanId)) : Buffer.alloc(0),
|
||||
traceState: isSet(object.traceState) ? globalThis.String(object.traceState) : "",
|
||||
attributes: globalThis.Array.isArray(object?.attributes)
|
||||
@@ -1418,14 +1441,19 @@ function base64FromBytes(arr: Uint8Array): string {
|
||||
|
||||
type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
|
||||
|
||||
export type DeepPartial<T> = T extends Builtin ? T
|
||||
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
export type DeepPartial<T> = T extends Builtin
|
||||
? T
|
||||
: T extends globalThis.Array<infer U>
|
||||
? globalThis.Array<DeepPartial<U>>
|
||||
: T extends ReadonlyArray<infer U>
|
||||
? ReadonlyArray<DeepPartial<U>>
|
||||
: T extends {}
|
||||
? { [K in keyof T]?: DeepPartial<T[K]> }
|
||||
: Partial<T>;
|
||||
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never;
|
||||
export type Exact<P, I extends P> = P extends Builtin ? P
|
||||
export type Exact<P, I extends P> = P extends Builtin
|
||||
? P
|
||||
: P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };
|
||||
|
||||
function longToBigint(long: Long) {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { permissiveAbility, superAbility, denyAbility, buildFallbackAbility, buildJwtAbility } from "./ability.js";
|
||||
import {
|
||||
permissiveAbility,
|
||||
superAbility,
|
||||
denyAbility,
|
||||
buildFallbackAbility,
|
||||
buildJwtAbility,
|
||||
} from "./ability.js";
|
||||
|
||||
describe("permissiveAbility", () => {
|
||||
it("allows any action on any resource type", () => {
|
||||
|
||||
@@ -91,7 +91,10 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
|
||||
// pre-RBAC routes that haven't been migrated, but it's a dead
|
||||
// code path for any route that uses `createLoaderApiRoute` /
|
||||
// `createActionApiRoute`.
|
||||
const rawToken = request.headers.get("Authorization")?.replace(/^Bearer /, "").trim();
|
||||
const rawToken = request.headers
|
||||
.get("Authorization")
|
||||
?.replace(/^Bearer /, "")
|
||||
.trim();
|
||||
if (!rawToken) return { ok: false, status: 401, error: "Invalid or Missing API key" };
|
||||
|
||||
if (options?.allowJWT && isPublicJWT(rawToken)) {
|
||||
@@ -165,9 +168,7 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
|
||||
},
|
||||
},
|
||||
parentEnvironment: { select: { id: true, apiKey: true } },
|
||||
childEnvironments: branchName
|
||||
? { where: { branchName, archivedAt: null } }
|
||||
: undefined,
|
||||
childEnvironments: branchName ? { where: { branchName, archivedAt: null } } : undefined,
|
||||
} as const;
|
||||
let env = await this.replica.runtimeEnvironment.findFirst({
|
||||
where: { apiKey: rawToken },
|
||||
@@ -338,7 +339,10 @@ class RoleBaseAccessFallbackController implements RoleBaseAccessController {
|
||||
request: Request,
|
||||
context: { organizationId?: string; projectId?: string }
|
||||
): Promise<UserActorAuthResult> {
|
||||
const rawToken = request.headers.get("Authorization")?.replace(/^Bearer /, "").trim();
|
||||
const rawToken = request.headers
|
||||
.get("Authorization")
|
||||
?.replace(/^Bearer /, "")
|
||||
.trim();
|
||||
if (!rawToken || !isUserActorToken(rawToken)) {
|
||||
return { ok: false, status: 401, error: "Invalid or Missing user-actor token" };
|
||||
}
|
||||
@@ -431,7 +435,9 @@ function isPublicJWT(token: string): boolean {
|
||||
const parts = token.split(".");
|
||||
if (parts.length !== 3) return false;
|
||||
try {
|
||||
const payload = JSON.parse(Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8"));
|
||||
const payload = JSON.parse(
|
||||
Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8")
|
||||
);
|
||||
return payload !== null && typeof payload === "object" && payload.pub === true;
|
||||
} catch {
|
||||
return false;
|
||||
@@ -442,7 +448,9 @@ function extractJWTSub(token: string): string | undefined {
|
||||
const parts = token.split(".");
|
||||
if (parts.length !== 3) return undefined;
|
||||
try {
|
||||
const payload = JSON.parse(Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8"));
|
||||
const payload = JSON.parse(
|
||||
Buffer.from(parts[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8")
|
||||
);
|
||||
return payload !== null && typeof payload === "object" && typeof payload.sub === "string"
|
||||
? payload.sub
|
||||
: undefined;
|
||||
|
||||
@@ -108,10 +108,8 @@ class LazyController implements RoleBaseAccessController {
|
||||
// specifier in the error message is the plugin's own moduleName.
|
||||
const code = (err as NodeJS.ErrnoException | undefined)?.code;
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
const isModuleNotFound =
|
||||
code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
|
||||
const isPluginItselfMissing =
|
||||
isModuleNotFound && message.includes(moduleName);
|
||||
const isModuleNotFound = code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND";
|
||||
const isPluginItselfMissing = isModuleNotFound && message.includes(moduleName);
|
||||
|
||||
if (!isPluginItselfMissing) {
|
||||
// Either the error wasn't a missing-module error at all, or the
|
||||
@@ -122,9 +120,7 @@ class LazyController implements RoleBaseAccessController {
|
||||
err
|
||||
);
|
||||
} else if (process.env.RBAC_LOG_FALLBACK === "1") {
|
||||
console.log(
|
||||
"RBAC: no plugin installed (ERR_MODULE_NOT_FOUND); using fallback"
|
||||
);
|
||||
console.log("RBAC: no plugin installed (ERR_MODULE_NOT_FOUND); using fallback");
|
||||
}
|
||||
|
||||
// Fail-fast for deployments that require plugins to be present. Set
|
||||
@@ -135,9 +131,7 @@ class LazyController implements RoleBaseAccessController {
|
||||
// rolled back. Self-hosters leave REQUIRE_PLUGINS unset and continue
|
||||
// to use the fallback when no plugin is installed.
|
||||
if (process.env.REQUIRE_PLUGINS === "1") {
|
||||
throw new Error(
|
||||
`REQUIRE_PLUGINS=1 but plugin "${moduleName}" did not load: ${message}`
|
||||
);
|
||||
throw new Error(`REQUIRE_PLUGINS=1 but plugin "${moduleName}" did not load: ${message}`);
|
||||
}
|
||||
|
||||
return new RoleBaseAccessFallback(prisma, {
|
||||
@@ -289,10 +283,7 @@ class LazyController implements RoleBaseAccessController {
|
||||
class RoleBaseAccess {
|
||||
// Synchronous — returns a lazy controller that resolves any installed
|
||||
// plugin on first call.
|
||||
create(
|
||||
prisma: RbacPrismaInput,
|
||||
options?: RbacCreateOptions
|
||||
): RoleBaseAccessController {
|
||||
create(prisma: RbacPrismaInput, options?: RbacCreateOptions): RoleBaseAccessController {
|
||||
return new LazyController(prisma, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user