@vellumai/assistant 0.11.9-dev.202609081913.93e93af → 0.11.9-dev.202609082015.1ff08e1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
  2. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
  3. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  4. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/plan-credit.ts +66 -0
  5. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
  6. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
  7. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  8. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/plan-credit.ts +66 -0
  9. package/node_modules/@vellumai/service-contracts/package.json +2 -1
  10. package/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
  11. package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  12. package/node_modules/@vellumai/service-contracts/src/plan-credit.ts +66 -0
  13. package/openapi.yaml +72 -5
  14. package/package.json +1 -1
  15. package/src/__tests__/mcp-config-secret-boundary.test.ts +2 -0
  16. package/src/__tests__/memory-config-file-parity.test.ts +18 -0
  17. package/src/api/constants/personality-sliders.test.ts +21 -0
  18. package/src/api/constants/personality-sliders.ts +64 -0
  19. package/src/api/index.ts +8 -0
  20. package/src/calls/voice-session-bridge.ts +26 -0
  21. package/src/cli/commands/config.help.ts +3 -1
  22. package/src/cli/commands/memory/worker.ts +1 -1
  23. package/src/cli/commands/platform/__tests__/credits-format.test.ts +94 -5
  24. package/src/cli/commands/platform/__tests__/credits.test.ts +10 -0
  25. package/src/cli/commands/platform/credits-format.ts +57 -0
  26. package/src/cli/commands/platform/index.help.ts +19 -3
  27. package/src/config/schemas/memory-storage.test.ts +39 -0
  28. package/src/config/schemas/memory-storage.ts +21 -0
  29. package/src/daemon/__tests__/embedding-reconcile.test.ts +77 -0
  30. package/src/daemon/__tests__/lifecycle-embedding-reconcile.test.ts +3 -0
  31. package/src/daemon/embedding-reconcile.ts +64 -1
  32. package/src/daemon/handlers/config-embeddings.ts +31 -0
  33. package/src/live-voice/__tests__/live-voice-photo.test.ts +72 -0
  34. package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +81 -0
  35. package/src/live-voice/live-voice-photo.ts +68 -4
  36. package/src/live-voice/live-voice-session.ts +36 -2
  37. package/src/live-voice/protocol.ts +98 -1
  38. package/src/persistence/conversation-crud.ts +38 -0
  39. package/src/persistence/embeddings/embedding-backend.test.ts +162 -0
  40. package/src/persistence/embeddings/embedding-backend.ts +148 -11
  41. package/src/persistence/embeddings/embedding-openai.test.ts +113 -0
  42. package/src/persistence/embeddings/embedding-openai.ts +55 -4
  43. package/src/persistence/embeddings/embedding-types.test.ts +24 -0
  44. package/src/persistence/embeddings/embedding-types.ts +25 -1
  45. package/src/persistence/job-utils.ts +6 -2
  46. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +1 -0
  47. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +11 -3
  48. package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +20 -0
  49. package/src/plugins/defaults/memory/src/memory-worker-routes.ts +3 -1
  50. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +1 -0
  51. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +1 -0
  52. package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +82 -0
  53. package/src/plugins/defaults/memory/v3/section-dense-store.ts +9 -27
  54. package/src/providers/__tests__/provider-secret-catalog.test.ts +4 -0
  55. package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +51 -0
  56. package/src/providers/openai/chat-completions-provider.ts +24 -4
  57. package/src/providers/provider-secret-catalog.ts +11 -1
  58. package/src/providers/vellum/client.ts +14 -1
  59. package/src/providers/vellum/personality-directions.test.ts +163 -0
  60. package/src/providers/vellum/personality-directions.ts +120 -0
  61. package/src/runtime/routes/__tests__/platform-credits-routes.test.ts +99 -5
  62. package/src/runtime/routes/conversation-query-routes.ts +34 -4
  63. package/src/runtime/routes/platform-routes.ts +121 -24
@@ -26,7 +26,8 @@
26
26
  "./error": "./src/error.ts",
27
27
  "./reactions": "./src/reactions.ts",
28
28
  "./guardian-requests": "./src/guardian-requests.ts",
29
- "./platform-credential": "./src/platform-credential.ts"
29
+ "./platform-credential": "./src/platform-credential.ts",
30
+ "./plan-credit": "./src/plan-credit.ts"
30
31
  },
31
32
  "scripts": {
32
33
  "typecheck": "bunx tsc --noEmit",
@@ -0,0 +1,51 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ extraCreditUsd,
5
+ planCreditUsedFraction,
6
+ usageGrantRatio,
7
+ } from "../plan-credit.js";
8
+
9
+ describe("usageGrantRatio", () => {
10
+ test("reads the used share and clamps to 0..1", () => {
11
+ expect(usageGrantRatio(20, 9.1)).toBeCloseTo(0.545);
12
+ expect(usageGrantRatio(20, 0)).toBe(1);
13
+ expect(usageGrantRatio(20, 25)).toBe(0);
14
+ });
15
+
16
+ test("has no reading without both figures or with nothing granted", () => {
17
+ expect(usageGrantRatio(null, 5)).toBeNull();
18
+ expect(usageGrantRatio(20, null)).toBeNull();
19
+ expect(usageGrantRatio(0, 0)).toBeNull();
20
+ });
21
+ });
22
+
23
+ describe("planCreditUsedFraction", () => {
24
+ test("prefers the ratio whatever the plan", () => {
25
+ expect(planCreditUsedFraction(20, 9.1, "base")).toBeCloseTo(0.545);
26
+ expect(planCreditUsedFraction(20, 9.1, null)).toBeCloseTo(0.545);
27
+ });
28
+
29
+ test("treats a Pro plan with nothing granted as fully spent", () => {
30
+ expect(planCreditUsedFraction(0, 0, "pro")).toBe(1);
31
+ expect(planCreditUsedFraction(0, null, "pro")).toBe(1);
32
+ });
33
+
34
+ test("gives a base or unknown plan with nothing granted no reading", () => {
35
+ expect(planCreditUsedFraction(0, 0, "base")).toBeNull();
36
+ expect(planCreditUsedFraction(0, 0, null)).toBeNull();
37
+ expect(planCreditUsedFraction(null, null, "pro")).toBeNull();
38
+ });
39
+ });
40
+
41
+ describe("extraCreditUsd", () => {
42
+ test("nets unused grant credit out of the balance to the cent", () => {
43
+ expect(extraCreditUsd(42.17, 9.1)).toBe(33.07);
44
+ expect(extraCreditUsd(34.65, 9.1)).toBe(25.55);
45
+ });
46
+
47
+ test("never goes below zero", () => {
48
+ expect(extraCreditUsd(5, 9.1)).toBe(0);
49
+ expect(extraCreditUsd(-2.5, 0)).toBe(0);
50
+ });
51
+ });
@@ -28,6 +28,7 @@ export * from "./rpc.js";
28
28
  export * from "./trust-rules.js";
29
29
  export * from "./ingress.js";
30
30
  export * from "./no-response.js";
31
+ export * from "./plan-credit.js";
31
32
  export * from "./platform-credential.js";
32
33
  export * from "./remote-web-pairing.js";
33
34
  export * from "./twilio-ingress.js";
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Plan-credit derivations shared by the assistant runtime's `platform credits`
3
+ * route and the web client's usage meter, so both read the billing summary's
4
+ * grant figures the same way and can never quote different readings.
5
+ */
6
+
7
+ export type BillingPlanId = "base" | "pro";
8
+
9
+ function clamp01(value: number): number {
10
+ if (!Number.isFinite(value) || value < 0) {
11
+ return 0;
12
+ }
13
+ return value > 1 ? 1 : value;
14
+ }
15
+
16
+ /**
17
+ * How much of the usage credit an account was granted it has already used:
18
+ * the granted total less what is still unused, over that total. The initial
19
+ * $5 grant burns 0 to 100% as it is spent, and a further grant grows the total
20
+ * so the bar drops back. Null when nothing was ever granted, or when the
21
+ * platform reports neither figure, which has no honest reading rather than a
22
+ * full or empty bar.
23
+ */
24
+ export function usageGrantRatio(
25
+ totalUsd: number | null,
26
+ availableUsd: number | null,
27
+ ): number | null {
28
+ if (totalUsd == null || availableUsd == null || totalUsd <= 0) {
29
+ return null;
30
+ }
31
+ return clamp01((totalUsd - availableUsd) / totalUsd);
32
+ }
33
+
34
+ /**
35
+ * The plan-credit reading with the plan's fallback applied. The grant figures
36
+ * count only unexpired grants, so a Pro subscription whose grants total
37
+ * nothing has used or expired everything it was granted (a full bar, with
38
+ * nothing scheduled to refill it), while a base plan in that position was
39
+ * never granted anything (no reading). An unknown plan gets the ratio when
40
+ * the figures allow one and no fallback otherwise.
41
+ */
42
+ export function planCreditUsedFraction(
43
+ totalUsd: number | null,
44
+ availableUsd: number | null,
45
+ planId: BillingPlanId | null,
46
+ ): number | null {
47
+ const ratio = usageGrantRatio(totalUsd, availableUsd);
48
+ if (ratio != null) {
49
+ return ratio;
50
+ }
51
+ if (planId === "pro" && totalUsd != null && totalUsd <= 0) {
52
+ return 1;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * Credit bought or earned on top of the plan-included grants: the balance less
59
+ * whatever is still unused on those grants, never below zero, to the cent.
60
+ */
61
+ export function extraCreditUsd(
62
+ balanceUsd: number,
63
+ availableUsd: number,
64
+ ): number {
65
+ return Math.round(Math.max(0, balanceUsd - availableUsd) * 100) / 100;
66
+ }
@@ -26,7 +26,8 @@
26
26
  "./error": "./src/error.ts",
27
27
  "./reactions": "./src/reactions.ts",
28
28
  "./guardian-requests": "./src/guardian-requests.ts",
29
- "./platform-credential": "./src/platform-credential.ts"
29
+ "./platform-credential": "./src/platform-credential.ts",
30
+ "./plan-credit": "./src/plan-credit.ts"
30
31
  },
31
32
  "scripts": {
32
33
  "typecheck": "bunx tsc --noEmit",
@@ -0,0 +1,51 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ extraCreditUsd,
5
+ planCreditUsedFraction,
6
+ usageGrantRatio,
7
+ } from "../plan-credit.js";
8
+
9
+ describe("usageGrantRatio", () => {
10
+ test("reads the used share and clamps to 0..1", () => {
11
+ expect(usageGrantRatio(20, 9.1)).toBeCloseTo(0.545);
12
+ expect(usageGrantRatio(20, 0)).toBe(1);
13
+ expect(usageGrantRatio(20, 25)).toBe(0);
14
+ });
15
+
16
+ test("has no reading without both figures or with nothing granted", () => {
17
+ expect(usageGrantRatio(null, 5)).toBeNull();
18
+ expect(usageGrantRatio(20, null)).toBeNull();
19
+ expect(usageGrantRatio(0, 0)).toBeNull();
20
+ });
21
+ });
22
+
23
+ describe("planCreditUsedFraction", () => {
24
+ test("prefers the ratio whatever the plan", () => {
25
+ expect(planCreditUsedFraction(20, 9.1, "base")).toBeCloseTo(0.545);
26
+ expect(planCreditUsedFraction(20, 9.1, null)).toBeCloseTo(0.545);
27
+ });
28
+
29
+ test("treats a Pro plan with nothing granted as fully spent", () => {
30
+ expect(planCreditUsedFraction(0, 0, "pro")).toBe(1);
31
+ expect(planCreditUsedFraction(0, null, "pro")).toBe(1);
32
+ });
33
+
34
+ test("gives a base or unknown plan with nothing granted no reading", () => {
35
+ expect(planCreditUsedFraction(0, 0, "base")).toBeNull();
36
+ expect(planCreditUsedFraction(0, 0, null)).toBeNull();
37
+ expect(planCreditUsedFraction(null, null, "pro")).toBeNull();
38
+ });
39
+ });
40
+
41
+ describe("extraCreditUsd", () => {
42
+ test("nets unused grant credit out of the balance to the cent", () => {
43
+ expect(extraCreditUsd(42.17, 9.1)).toBe(33.07);
44
+ expect(extraCreditUsd(34.65, 9.1)).toBe(25.55);
45
+ });
46
+
47
+ test("never goes below zero", () => {
48
+ expect(extraCreditUsd(5, 9.1)).toBe(0);
49
+ expect(extraCreditUsd(-2.5, 0)).toBe(0);
50
+ });
51
+ });
@@ -28,6 +28,7 @@ export * from "./rpc.js";
28
28
  export * from "./trust-rules.js";
29
29
  export * from "./ingress.js";
30
30
  export * from "./no-response.js";
31
+ export * from "./plan-credit.js";
31
32
  export * from "./platform-credential.js";
32
33
  export * from "./remote-web-pairing.js";
33
34
  export * from "./twilio-ingress.js";
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Plan-credit derivations shared by the assistant runtime's `platform credits`
3
+ * route and the web client's usage meter, so both read the billing summary's
4
+ * grant figures the same way and can never quote different readings.
5
+ */
6
+
7
+ export type BillingPlanId = "base" | "pro";
8
+
9
+ function clamp01(value: number): number {
10
+ if (!Number.isFinite(value) || value < 0) {
11
+ return 0;
12
+ }
13
+ return value > 1 ? 1 : value;
14
+ }
15
+
16
+ /**
17
+ * How much of the usage credit an account was granted it has already used:
18
+ * the granted total less what is still unused, over that total. The initial
19
+ * $5 grant burns 0 to 100% as it is spent, and a further grant grows the total
20
+ * so the bar drops back. Null when nothing was ever granted, or when the
21
+ * platform reports neither figure, which has no honest reading rather than a
22
+ * full or empty bar.
23
+ */
24
+ export function usageGrantRatio(
25
+ totalUsd: number | null,
26
+ availableUsd: number | null,
27
+ ): number | null {
28
+ if (totalUsd == null || availableUsd == null || totalUsd <= 0) {
29
+ return null;
30
+ }
31
+ return clamp01((totalUsd - availableUsd) / totalUsd);
32
+ }
33
+
34
+ /**
35
+ * The plan-credit reading with the plan's fallback applied. The grant figures
36
+ * count only unexpired grants, so a Pro subscription whose grants total
37
+ * nothing has used or expired everything it was granted (a full bar, with
38
+ * nothing scheduled to refill it), while a base plan in that position was
39
+ * never granted anything (no reading). An unknown plan gets the ratio when
40
+ * the figures allow one and no fallback otherwise.
41
+ */
42
+ export function planCreditUsedFraction(
43
+ totalUsd: number | null,
44
+ availableUsd: number | null,
45
+ planId: BillingPlanId | null,
46
+ ): number | null {
47
+ const ratio = usageGrantRatio(totalUsd, availableUsd);
48
+ if (ratio != null) {
49
+ return ratio;
50
+ }
51
+ if (planId === "pro" && totalUsd != null && totalUsd <= 0) {
52
+ return 1;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * Credit bought or earned on top of the plan-included grants: the balance less
59
+ * whatever is still unused on those grants, never below zero, to the cent.
60
+ */
61
+ export function extraCreditUsd(
62
+ balanceUsd: number,
63
+ availableUsd: number,
64
+ ): number {
65
+ return Math.round(Math.max(0, balanceUsd - availableUsd) * 100) / 100;
66
+ }
@@ -26,7 +26,8 @@
26
26
  "./error": "./src/error.ts",
27
27
  "./reactions": "./src/reactions.ts",
28
28
  "./guardian-requests": "./src/guardian-requests.ts",
29
- "./platform-credential": "./src/platform-credential.ts"
29
+ "./platform-credential": "./src/platform-credential.ts",
30
+ "./plan-credit": "./src/plan-credit.ts"
30
31
  },
31
32
  "scripts": {
32
33
  "typecheck": "bunx tsc --noEmit",
@@ -0,0 +1,51 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ extraCreditUsd,
5
+ planCreditUsedFraction,
6
+ usageGrantRatio,
7
+ } from "../plan-credit.js";
8
+
9
+ describe("usageGrantRatio", () => {
10
+ test("reads the used share and clamps to 0..1", () => {
11
+ expect(usageGrantRatio(20, 9.1)).toBeCloseTo(0.545);
12
+ expect(usageGrantRatio(20, 0)).toBe(1);
13
+ expect(usageGrantRatio(20, 25)).toBe(0);
14
+ });
15
+
16
+ test("has no reading without both figures or with nothing granted", () => {
17
+ expect(usageGrantRatio(null, 5)).toBeNull();
18
+ expect(usageGrantRatio(20, null)).toBeNull();
19
+ expect(usageGrantRatio(0, 0)).toBeNull();
20
+ });
21
+ });
22
+
23
+ describe("planCreditUsedFraction", () => {
24
+ test("prefers the ratio whatever the plan", () => {
25
+ expect(planCreditUsedFraction(20, 9.1, "base")).toBeCloseTo(0.545);
26
+ expect(planCreditUsedFraction(20, 9.1, null)).toBeCloseTo(0.545);
27
+ });
28
+
29
+ test("treats a Pro plan with nothing granted as fully spent", () => {
30
+ expect(planCreditUsedFraction(0, 0, "pro")).toBe(1);
31
+ expect(planCreditUsedFraction(0, null, "pro")).toBe(1);
32
+ });
33
+
34
+ test("gives a base or unknown plan with nothing granted no reading", () => {
35
+ expect(planCreditUsedFraction(0, 0, "base")).toBeNull();
36
+ expect(planCreditUsedFraction(0, 0, null)).toBeNull();
37
+ expect(planCreditUsedFraction(null, null, "pro")).toBeNull();
38
+ });
39
+ });
40
+
41
+ describe("extraCreditUsd", () => {
42
+ test("nets unused grant credit out of the balance to the cent", () => {
43
+ expect(extraCreditUsd(42.17, 9.1)).toBe(33.07);
44
+ expect(extraCreditUsd(34.65, 9.1)).toBe(25.55);
45
+ });
46
+
47
+ test("never goes below zero", () => {
48
+ expect(extraCreditUsd(5, 9.1)).toBe(0);
49
+ expect(extraCreditUsd(-2.5, 0)).toBe(0);
50
+ });
51
+ });
@@ -28,6 +28,7 @@ export * from "./rpc.js";
28
28
  export * from "./trust-rules.js";
29
29
  export * from "./ingress.js";
30
30
  export * from "./no-response.js";
31
+ export * from "./plan-credit.js";
31
32
  export * from "./platform-credential.js";
32
33
  export * from "./remote-web-pairing.js";
33
34
  export * from "./twilio-ingress.js";
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Plan-credit derivations shared by the assistant runtime's `platform credits`
3
+ * route and the web client's usage meter, so both read the billing summary's
4
+ * grant figures the same way and can never quote different readings.
5
+ */
6
+
7
+ export type BillingPlanId = "base" | "pro";
8
+
9
+ function clamp01(value: number): number {
10
+ if (!Number.isFinite(value) || value < 0) {
11
+ return 0;
12
+ }
13
+ return value > 1 ? 1 : value;
14
+ }
15
+
16
+ /**
17
+ * How much of the usage credit an account was granted it has already used:
18
+ * the granted total less what is still unused, over that total. The initial
19
+ * $5 grant burns 0 to 100% as it is spent, and a further grant grows the total
20
+ * so the bar drops back. Null when nothing was ever granted, or when the
21
+ * platform reports neither figure, which has no honest reading rather than a
22
+ * full or empty bar.
23
+ */
24
+ export function usageGrantRatio(
25
+ totalUsd: number | null,
26
+ availableUsd: number | null,
27
+ ): number | null {
28
+ if (totalUsd == null || availableUsd == null || totalUsd <= 0) {
29
+ return null;
30
+ }
31
+ return clamp01((totalUsd - availableUsd) / totalUsd);
32
+ }
33
+
34
+ /**
35
+ * The plan-credit reading with the plan's fallback applied. The grant figures
36
+ * count only unexpired grants, so a Pro subscription whose grants total
37
+ * nothing has used or expired everything it was granted (a full bar, with
38
+ * nothing scheduled to refill it), while a base plan in that position was
39
+ * never granted anything (no reading). An unknown plan gets the ratio when
40
+ * the figures allow one and no fallback otherwise.
41
+ */
42
+ export function planCreditUsedFraction(
43
+ totalUsd: number | null,
44
+ availableUsd: number | null,
45
+ planId: BillingPlanId | null,
46
+ ): number | null {
47
+ const ratio = usageGrantRatio(totalUsd, availableUsd);
48
+ if (ratio != null) {
49
+ return ratio;
50
+ }
51
+ if (planId === "pro" && totalUsd != null && totalUsd <= 0) {
52
+ return 1;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * Credit bought or earned on top of the plan-included grants: the balance less
59
+ * whatever is still unused on those grants, never below zero, to the cent.
60
+ */
61
+ export function extraCreditUsd(
62
+ balanceUsd: number,
63
+ availableUsd: number,
64
+ ): number {
65
+ return Math.round(Math.max(0, balanceUsd - availableUsd) * 100) / 100;
66
+ }
package/openapi.yaml CHANGED
@@ -5102,7 +5102,7 @@ paths:
5102
5102
  put:
5103
5103
  operationId: config_embeddings_put
5104
5104
  summary: Set embedding config
5105
- description: Change the embedding provider and optionally model.
5105
+ description: Change the embedding provider, model, and optional custom endpoint.
5106
5106
  tags:
5107
5107
  - config
5108
5108
  requestBody:
@@ -5116,6 +5116,14 @@ paths:
5116
5116
  type: string
5117
5117
  model:
5118
5118
  type: string
5119
+ baseUrl:
5120
+ type: string
5121
+ dimensions:
5122
+ anyOf:
5123
+ - type: integer
5124
+ exclusiveMinimum: 0
5125
+ maximum: 9007199254740991
5126
+ - type: "null"
5119
5127
  required:
5120
5128
  - provider
5121
5129
  responses:
@@ -20044,6 +20052,7 @@ paths:
20044
20052
  - openai
20045
20053
  - gemini
20046
20054
  - ollama
20055
+ - custom
20047
20056
  - type: "null"
20048
20057
  model:
20049
20058
  anyOf:
@@ -24668,12 +24677,13 @@ paths:
24668
24677
  /v1/platform/credits:
24669
24678
  get:
24670
24679
  operationId: platform_credits_get
24671
- summary: Get the organization's remaining credit balance and daily-limit state
24680
+ summary: Get the organization's credit balance, plan-credit usage, and daily-limit state
24672
24681
  description:
24673
24682
  "Fetches the org's settled, pending, and effective (remaining) credit balance in USD from the platform
24674
- billing summary, plus the daily-limit state: today's spend counted against the daily credit limit (which
24675
- excludes spend covered by plan-included credits, so it is not total spend), the limit itself, and the
24676
- low-balance warning state."
24683
+ billing summary, plus plan-included credit usage (remaining, total, and the used fraction shown by the in-app
24684
+ usage meter), extra credit bought or earned on top, credit expiring within 30 days, and the daily-limit state:
24685
+ today's spend counted against the daily credit limit (which excludes spend covered by plan-included credits, so
24686
+ it is not total spend), the limit itself, and the low-balance warning state."
24677
24687
  tags:
24678
24688
  - platform
24679
24689
  responses:
@@ -24724,6 +24734,56 @@ paths:
24724
24734
  low_balance_warning:
24725
24735
  type: boolean
24726
24736
  description: True when the balance is above zero but below the low-balance threshold and auto top-up is not enabled.
24737
+ plan_credit_remaining:
24738
+ anyOf:
24739
+ - type: number
24740
+ - type: "null"
24741
+ description:
24742
+ Unused credit (USD) remaining on the unexpired plan-included grants (initial credit, Pro credit bundle).
24743
+ Null when the platform did not report grant figures.
24744
+ plan_credit_total:
24745
+ anyOf:
24746
+ - type: number
24747
+ - type: "null"
24748
+ description:
24749
+ Total credit (USD) those plan-included grants were worth, net of refunds. Null when the platform did not
24750
+ report grant figures.
24751
+ plan_credit_used_fraction:
24752
+ anyOf:
24753
+ - type: number
24754
+ - type: "null"
24755
+ description:
24756
+ "Share of the plan-included credit already used, from 0 to 1: the same reading as the in-app usage meter. A
24757
+ Pro subscription whose unexpired grants total nothing reads as 1 (everything granted is used or
24758
+ expired). Null when there is no usable reading: grant figures missing, or a zero total on a base
24759
+ or unknown plan."
24760
+ plan_credits_spent:
24761
+ anyOf:
24762
+ - type: boolean
24763
+ - type: "null"
24764
+ description:
24765
+ True when the plan-included credit is used up or expired. Whether further managed usage is funded is
24766
+ extra_credit_remaining (zero means the organization is out of credit). Null when there is no
24767
+ plan-credit reading.
24768
+ extra_credit_remaining:
24769
+ anyOf:
24770
+ - type: number
24771
+ - type: "null"
24772
+ description:
24773
+ "Credit (USD) bought or earned on top of the plan-included grants: remaining minus plan_credit_remaining,
24774
+ floored at zero. Null when grant figures are missing."
24775
+ credits_expiring_soon:
24776
+ anyOf:
24777
+ - type: number
24778
+ - type: "null"
24779
+ description:
24780
+ Unexpired credit (USD) on grants that expire within the next 30 days. Null when the platform did not report
24781
+ it.
24782
+ next_credit_expiry_at:
24783
+ anyOf:
24784
+ - type: string
24785
+ - type: "null"
24786
+ description: Earliest upcoming expiry (ISO 8601) across grants that still hold credit, or null when none is scheduled.
24727
24787
  required:
24728
24788
  - remaining
24729
24789
  - settled
@@ -24737,6 +24797,13 @@ paths:
24737
24797
  - daily_limit_snoozed
24738
24798
  - low_balance_threshold
24739
24799
  - low_balance_warning
24800
+ - plan_credit_remaining
24801
+ - plan_credit_total
24802
+ - plan_credit_used_fraction
24803
+ - plan_credits_spent
24804
+ - extra_credit_remaining
24805
+ - credits_expiring_soon
24806
+ - next_credit_expiry_at
24740
24807
  additionalProperties: false
24741
24808
  /v1/platform/disconnect:
24742
24809
  post:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.11.9-dev.202609081913.93e93af",
3
+ "version": "0.11.9-dev.202609082015.1ff08e1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -82,6 +82,8 @@ mock.module("../persistence/embeddings/embedding-backend.js", () => ({
82
82
  vectors: [],
83
83
  }),
84
84
  geminiCacheExtras: () => [],
85
+ customCacheExtras: () => [],
86
+ durableEmbeddingCacheExtras: () => [],
85
87
  generateSparseEmbedding: () => ({ indices: [], values: [] }),
86
88
  getMemoryBackendStatus: async () => ({
87
89
  enabled: false,
@@ -101,6 +101,24 @@ describe("memory config file parity", () => {
101
101
  expect(memory.embeddings.provider).toBe("openai");
102
102
  });
103
103
 
104
+ test("custom embedding endpoint knobs are visible and identical", () => {
105
+ writeConfig({
106
+ memory: {
107
+ embeddings: {
108
+ provider: "custom",
109
+ baseUrl: "http://127.0.0.1:4000/v1",
110
+ customModel: "text-embedding-3-small",
111
+ customDimensions: 1024,
112
+ },
113
+ },
114
+ });
115
+ const memory = expectParity();
116
+ expect(memory.embeddings.provider).toBe("custom");
117
+ expect(memory.embeddings.baseUrl).toBe("http://127.0.0.1:4000/v1");
118
+ expect(memory.embeddings.customModel).toBe("text-embedding-3-small");
119
+ expect(memory.embeddings.customDimensions).toBe(1024);
120
+ });
121
+
104
122
  test("cross-field invariant: segmentation overlap >= target falls back like the loader", () => {
105
123
  writeConfig({
106
124
  memory: {
@@ -0,0 +1,21 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ PERSONALITY_AXIS_IDS,
5
+ PERSONALITY_DIRECTION_AXES,
6
+ PERSONALITY_SLIDER_DEFAULT,
7
+ PERSONALITY_SLIDERS_PATH,
8
+ } from "./personality-sliders.js";
9
+
10
+ describe("personality slider contract", () => {
11
+ test("sidecar path and default stay centered", () => {
12
+ expect(PERSONALITY_SLIDERS_PATH).toBe("data/personality-sliders.json");
13
+ expect(PERSONALITY_SLIDER_DEFAULT).toBe(50);
14
+ });
15
+
16
+ test("every slider axis has a left and right direction pole", () => {
17
+ expect(PERSONALITY_DIRECTION_AXES.map((axis) => axis.sliderId)).toEqual(
18
+ Object.values(PERSONALITY_AXIS_IDS),
19
+ );
20
+ });
21
+ });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Personality slider sidecar path, the five 0-100 axis ids, and the
3
+ * hosted-Qwen direction poles those sliders map onto.
4
+ *
5
+ * The web writes `data/personality-sliders.json`. The assistant reads the
6
+ * same path and maps each slider onto one left/right pole. Both import
7
+ * these constants from `@vellumai/assistant-api` so the ids cannot drift.
8
+ */
9
+
10
+ /** Workspace-relative sidecar holding the five 0-100 slider values. */
11
+ export const PERSONALITY_SLIDERS_PATH = "data/personality-sliders.json";
12
+
13
+ /** Sliders start centered. Center is no steer on the hosted-Qwen route. */
14
+ export const PERSONALITY_SLIDER_DEFAULT = 50;
15
+
16
+ /**
17
+ * Axis ids the personality sliders key their values by. Each is 0-100 with
18
+ * 0 = the left label and 100 = the right label.
19
+ */
20
+ export const PERSONALITY_AXIS_IDS = {
21
+ companionCoworker: "companion-coworker",
22
+ genzBoomer: "genz-boomer",
23
+ executeCollaborate: "execute-collaborate",
24
+ playfulSerious: "playful-serious",
25
+ politeUnfiltered: "polite-unfiltered",
26
+ } as const;
27
+
28
+ export type PersonalityAxisId =
29
+ (typeof PERSONALITY_AXIS_IDS)[keyof typeof PERSONALITY_AXIS_IDS];
30
+
31
+ /**
32
+ * One-sided direction poles for each slider. Center (50) activates neither.
33
+ * Values below 50 activate `left`; values above 50 activate `right`.
34
+ */
35
+ export const PERSONALITY_DIRECTION_AXES = [
36
+ {
37
+ sliderId: PERSONALITY_AXIS_IDS.companionCoworker,
38
+ left: "companion",
39
+ right: "coworker",
40
+ },
41
+ {
42
+ sliderId: PERSONALITY_AXIS_IDS.genzBoomer,
43
+ left: "genz",
44
+ right: "boomer",
45
+ },
46
+ {
47
+ sliderId: PERSONALITY_AXIS_IDS.executeCollaborate,
48
+ left: "independent",
49
+ right: "collaborative",
50
+ },
51
+ {
52
+ sliderId: PERSONALITY_AXIS_IDS.playfulSerious,
53
+ left: "playful",
54
+ right: "serious",
55
+ },
56
+ {
57
+ sliderId: PERSONALITY_AXIS_IDS.politeUnfiltered,
58
+ left: "polite",
59
+ right: "unfiltered",
60
+ },
61
+ ] as const;
62
+
63
+ export type PersonalityDirectionAxis =
64
+ (typeof PERSONALITY_DIRECTION_AXES)[number];