pi-meta-oauth 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/extensions/meta.ts +5 -1
- package/package.json +1 -1
- package/src/meta/models.ts +90 -7
- package/src/meta/muse-policy.ts +4 -5
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ Prefer a static key instead? Set `META_API_KEY` (or `MODEL_API_KEY`) and skip
|
|
|
48
48
|
|
|
49
49
|
## Models
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Bundled models use a 1,048,576-token context window, up to 256K output tokens, image input, and reasoning levels `minimal`, `low`, `medium`, `high`, and `xhigh`. `muse-spark-1.3`, `muse-wonder-1.0`, and `muse-wonder-full-1.0` additionally support `max`; their `-contributor` variants do too when [opted in](#contributor-max-opt-in). Meta's catalog endpoint has returned bare model IDs without names, prices, or modalities since at least 2026-10-23, so these bundled definitions supply that metadata for known IDs; an unknown ID still appears with default values.
|
|
52
52
|
|
|
53
53
|
| id | pricing (input/output/cached) $/M |
|
|
54
54
|
| --- | --- |
|
|
@@ -57,6 +57,12 @@ Fallback models use a 1,048,576-token context window, up to 256K output tokens,
|
|
|
57
57
|
| `muse-spark-1.2` | 1.25 / 4.25 / 0.15 |
|
|
58
58
|
| `muse-spark-1.2-contributor` | 0.10 / 0.20 / 0.002 |
|
|
59
59
|
| `muse-spark-1.1` | 1.25 / 4.25 / 0.15 |
|
|
60
|
+
| `muse-wonder-1.0` | 4.00 / 20.00 / 0.20 |
|
|
61
|
+
| `muse-wonder-1.0-contributor` | no published per-token rate (Muse Code subscription); Pi shows $0 |
|
|
62
|
+
| `muse-wonder-full-1.0` | no published per-token rate (Muse Code subscription); Pi shows $0 |
|
|
63
|
+
| `muse-wonder-full-1.0-contributor` | no published per-token rate (Muse Code subscription); Pi shows $0 |
|
|
64
|
+
|
|
65
|
+
The catalog also lists Meta's non-chat models, which are billed per generated image, per hour of audio, or per video frame rather than per token: the `muse-image-*`, `muse-voice-*`, and `sam-*` families. The extension hides them from the chat model list, including entries an earlier release cached in `models-store.json`.
|
|
60
66
|
|
|
61
67
|
> **Contributor-model privacy:** discounted contributor models allow Meta to use prompts and completions for product improvement, including training future Meta models. Use a standard model such as `muse-spark-1.3` if you do not want the contributor terms. See [Meta's model documentation](https://dev.meta.ai/docs/models).
|
|
62
68
|
|
|
@@ -135,10 +141,11 @@ also bypasses isolation and can run these probes when credentials are available.
|
|
|
135
141
|
The cache probe makes two billable Responses requests plus one retry on a cache
|
|
136
142
|
miss. The fingerprint probe makes two tiny Contributor-`max` requests; it sends
|
|
137
143
|
the header directly, independently of `META_MUSE_USER_AGENT`. The catalog probe
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
no usable
|
|
144
|
+
makes one catalog request and fails when a live model ID has neither a bundled
|
|
145
|
+
definition nor a non-chat prefix. All three probes resolve credentials from
|
|
146
|
+
`PI_META_LIVE_API_KEY`, `META_API_KEY`, `MODEL_API_KEY`, or an unexpired minted
|
|
147
|
+
key in `~/.pi/agent/auth.json`, in that order, and skip when no usable
|
|
148
|
+
credential exists.
|
|
142
149
|
|
|
143
150
|
```bash
|
|
144
151
|
bun run test:live tests/meta-cache.test.ts
|
package/extensions/meta.ts
CHANGED
|
@@ -15,7 +15,11 @@ export {
|
|
|
15
15
|
MUSE_USER_AGENT_ENV_VAR,
|
|
16
16
|
} from "../src/meta/constants.ts";
|
|
17
17
|
export { refreshMetaModels } from "../src/meta/model-store.ts";
|
|
18
|
-
export {
|
|
18
|
+
export {
|
|
19
|
+
isNonChatModelId,
|
|
20
|
+
metaFallbackCost,
|
|
21
|
+
toProviderModels,
|
|
22
|
+
} from "../src/meta/models.ts";
|
|
19
23
|
export { isMuseUserAgentEnabled } from "../src/meta/muse-policy.ts";
|
|
20
24
|
export {
|
|
21
25
|
loginMeta,
|
package/package.json
CHANGED
package/src/meta/models.ts
CHANGED
|
@@ -21,6 +21,24 @@ const CONTRIBUTOR_COST = {
|
|
|
21
21
|
cacheRead: 0.002,
|
|
22
22
|
cacheWrite: 0,
|
|
23
23
|
};
|
|
24
|
+
/** Meta Model API list price for muse-wonder-1.0 (dev.meta.ai pricing page, 2026-10-23). */
|
|
25
|
+
const WONDER_COST = {
|
|
26
|
+
input: 4,
|
|
27
|
+
output: 20,
|
|
28
|
+
cacheRead: 0.2,
|
|
29
|
+
cacheWrite: 0,
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Muse Wonder Full and the Wonder Contributor variants are reachable only
|
|
33
|
+
* through a Muse Code subscription; Meta publishes no per-token rate for
|
|
34
|
+
* them, so Pi shows $0. This is a representation of "unpriced", not a fact.
|
|
35
|
+
*/
|
|
36
|
+
const SUBSCRIPTION_ONLY_COST = {
|
|
37
|
+
input: 0,
|
|
38
|
+
output: 0,
|
|
39
|
+
cacheRead: 0,
|
|
40
|
+
cacheWrite: 0,
|
|
41
|
+
};
|
|
24
42
|
const UNKNOWN_MODEL_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
25
43
|
const THINKING_LEVELS = [
|
|
26
44
|
"minimal",
|
|
@@ -32,7 +50,13 @@ const THINKING_LEVELS = [
|
|
|
32
50
|
] as const;
|
|
33
51
|
type ThinkingLevelMap = NonNullable<MetaProviderModel["thinkingLevelMap"]>;
|
|
34
52
|
|
|
35
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Data-only definitions; callers always receive fresh model objects. The live
|
|
55
|
+
* catalog has carried no `metadata["muse-code"]` block since at least
|
|
56
|
+
* 2026-10-23, so names, prices, and image input for known IDs come from here.
|
|
57
|
+
* Spark first keeps the long-standing default model; after the first refresh
|
|
58
|
+
* the catalog's own order wins anyway.
|
|
59
|
+
*/
|
|
36
60
|
const FALLBACK_DEFINITIONS = [
|
|
37
61
|
{
|
|
38
62
|
id: "muse-spark-1.3",
|
|
@@ -64,8 +88,54 @@ const FALLBACK_DEFINITIONS = [
|
|
|
64
88
|
cost: STANDARD_COST,
|
|
65
89
|
max: false,
|
|
66
90
|
},
|
|
91
|
+
{
|
|
92
|
+
id: "muse-wonder-1.0",
|
|
93
|
+
name: "Muse Wonder 1.0",
|
|
94
|
+
cost: WONDER_COST,
|
|
95
|
+
max: true,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "muse-wonder-1.0-contributor",
|
|
99
|
+
name: "Muse Wonder 1.0 Contributor",
|
|
100
|
+
cost: SUBSCRIPTION_ONLY_COST,
|
|
101
|
+
max: false,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "muse-wonder-full-1.0",
|
|
105
|
+
name: "Muse Wonder Full 1.0",
|
|
106
|
+
cost: SUBSCRIPTION_ONLY_COST,
|
|
107
|
+
max: true,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "muse-wonder-full-1.0-contributor",
|
|
111
|
+
name: "Muse Wonder Full 1.0 Contributor",
|
|
112
|
+
cost: SUBSCRIPTION_ONLY_COST,
|
|
113
|
+
max: false,
|
|
114
|
+
},
|
|
67
115
|
] as const;
|
|
68
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Catalog families Meta bills per generated image, per hour of audio, or per
|
|
119
|
+
* video frame instead of per token (dev.meta.ai pricing page, 2026-10-23):
|
|
120
|
+
* Muse Image, Muse Voice Transcribe, and Segment Anything. They share the
|
|
121
|
+
* catalog with the chat models but are not chat models, so neither the live
|
|
122
|
+
* catalog nor a cached entry may list them as one. Prefixes, not exact IDs,
|
|
123
|
+
* so a new version of a family stays hidden without a code change.
|
|
124
|
+
*/
|
|
125
|
+
export const NON_CHAT_MODEL_ID_PREFIXES = [
|
|
126
|
+
"muse-image-",
|
|
127
|
+
"muse-voice-",
|
|
128
|
+
"sam-",
|
|
129
|
+
] as const;
|
|
130
|
+
|
|
131
|
+
export function isNonChatModelId(id: string): boolean {
|
|
132
|
+
return NON_CHAT_MODEL_ID_PREFIXES.some((prefix) => id.startsWith(prefix));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function isBundledModelId(id: string): boolean {
|
|
136
|
+
return FALLBACK_DEFINITIONS.some((model) => model.id === id);
|
|
137
|
+
}
|
|
138
|
+
|
|
69
139
|
function nonemptyString(value: unknown): string | undefined {
|
|
70
140
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
71
141
|
}
|
|
@@ -166,7 +236,7 @@ export function toProviderModels(catalog: unknown): MetaProviderModel[] {
|
|
|
166
236
|
for (const value of data) {
|
|
167
237
|
const entry = asRecord(value);
|
|
168
238
|
const id = nonemptyString(entry?.id);
|
|
169
|
-
if (!id || seen.has(id)) continue;
|
|
239
|
+
if (!id || seen.has(id) || isNonChatModelId(id)) continue;
|
|
170
240
|
const metadata = asRecord(asRecord(entry?.metadata)?.["muse-code"]);
|
|
171
241
|
if (metadata?.is_hidden === true) continue;
|
|
172
242
|
const fallback = defaultModel(id);
|
|
@@ -308,7 +378,14 @@ function storedCost(
|
|
|
308
378
|
return cost;
|
|
309
379
|
}
|
|
310
380
|
|
|
311
|
-
/**
|
|
381
|
+
/**
|
|
382
|
+
* Cache contents cross the same untrusted-data boundary as the remote catalog.
|
|
383
|
+
* For bundled IDs the name, price, and input come from FALLBACK_DEFINITIONS:
|
|
384
|
+
* the bare catalog cannot have advertised them, so a cached copy is at best an
|
|
385
|
+
* older release's bundled value and at worst its unknown-model default (0.7.4
|
|
386
|
+
* persisted Wonder as a $0 text-only model). Cached limits, effort names,
|
|
387
|
+
* headers, and compat flags are kept; unknown IDs restore every cached field.
|
|
388
|
+
*/
|
|
312
389
|
export function restoreProviderModels(value: unknown): MetaProviderModel[] {
|
|
313
390
|
if (!Array.isArray(value)) return [];
|
|
314
391
|
const models: MetaProviderModel[] = [];
|
|
@@ -321,12 +398,16 @@ export function restoreProviderModels(value: unknown): MetaProviderModel[] {
|
|
|
321
398
|
)
|
|
322
399
|
continue;
|
|
323
400
|
const id = nonemptyString(entry.id);
|
|
324
|
-
|
|
401
|
+
// A catalog persisted by an earlier release may hold non-chat IDs.
|
|
402
|
+
if (!id || seen.has(id) || isNonChatModelId(id)) continue;
|
|
325
403
|
const fallback = defaultModel(id);
|
|
404
|
+
const bundled = isBundledModelId(id);
|
|
326
405
|
models.push(
|
|
327
406
|
gateMuseMaxEffort({
|
|
328
407
|
...fallback,
|
|
329
|
-
name:
|
|
408
|
+
name: bundled
|
|
409
|
+
? fallback.name
|
|
410
|
+
: (nonemptyString(entry.name) ?? fallback.name),
|
|
330
411
|
api: "openai-responses",
|
|
331
412
|
// The extension only persists the direct endpoint; a cached URL must never redirect the key.
|
|
332
413
|
baseUrl: META_API_BASE_URL,
|
|
@@ -338,8 +419,10 @@ export function restoreProviderModels(value: unknown): MetaProviderModel[] {
|
|
|
338
419
|
entry.thinkingLevelMap,
|
|
339
420
|
fallback.thinkingLevelMap ?? {},
|
|
340
421
|
),
|
|
341
|
-
input:
|
|
342
|
-
|
|
422
|
+
input: bundled
|
|
423
|
+
? fallback.input
|
|
424
|
+
: modelInput(entry.input, fallback.input),
|
|
425
|
+
cost: bundled ? fallback.cost : storedCost(entry.cost, fallback.cost),
|
|
343
426
|
contextWindow: positiveInteger(
|
|
344
427
|
entry.contextWindow,
|
|
345
428
|
fallback.contextWindow,
|
package/src/meta/muse-policy.ts
CHANGED
|
@@ -9,11 +9,10 @@ export const MUSE_USER_AGENT_MODEL_IDS: ReadonlySet<string> = new Set([
|
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Models known to accept literal max effort with any User-Agent.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* cannot mask its fallback-declared support.
|
|
12
|
+
* Models known to accept literal max effort with any User-Agent. Each also
|
|
13
|
+
* has a bundled definition in models.ts that declares max, but they are
|
|
14
|
+
* listed here so the gate — which runs on every model list — is the single
|
|
15
|
+
* authority and a stale cached `max: null` cannot mask that support.
|
|
17
16
|
*/
|
|
18
17
|
export const MAX_EFFORT_MODEL_IDS: ReadonlySet<string> = new Set([
|
|
19
18
|
"muse-spark-1.3",
|