@wudao-org/providers 0.0.0-stage → 0.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +8 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/anthropic.d.ts +19 -0
- package/dist/anthropic.d.ts.map +1 -0
- package/dist/anthropic.js +621 -0
- package/dist/anthropic.js.map +1 -0
- package/dist/balance.d.ts +28 -0
- package/dist/balance.d.ts.map +1 -0
- package/dist/balance.js +105 -0
- package/dist/balance.js.map +1 -0
- package/dist/config.d.ts +328 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +623 -0
- package/dist/config.js.map +1 -0
- package/dist/dispatcher.d.ts +5 -0
- package/dist/dispatcher.d.ts.map +1 -0
- package/dist/dispatcher.js +21 -0
- package/dist/dispatcher.js.map +1 -0
- package/dist/effort-catalog.d.ts +17 -0
- package/dist/effort-catalog.d.ts.map +1 -0
- package/dist/effort-catalog.js +73 -0
- package/dist/effort-catalog.js.map +1 -0
- package/dist/error-body.d.ts +32 -0
- package/dist/error-body.d.ts.map +1 -0
- package/dist/error-body.js +74 -0
- package/dist/error-body.js.map +1 -0
- package/dist/header-validation.d.ts +57 -0
- package/dist/header-validation.d.ts.map +1 -0
- package/dist/header-validation.js +130 -0
- package/dist/header-validation.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/json-arguments.d.ts +17 -0
- package/dist/json-arguments.d.ts.map +1 -0
- package/dist/json-arguments.js +227 -0
- package/dist/json-arguments.js.map +1 -0
- package/dist/key-pool.d.ts +66 -0
- package/dist/key-pool.d.ts.map +1 -0
- package/dist/key-pool.js +207 -0
- package/dist/key-pool.js.map +1 -0
- package/dist/missing-reasoning-circuit.d.ts +17 -0
- package/dist/missing-reasoning-circuit.d.ts.map +1 -0
- package/dist/missing-reasoning-circuit.js +38 -0
- package/dist/missing-reasoning-circuit.js.map +1 -0
- package/dist/model-failure.d.ts +156 -0
- package/dist/model-failure.d.ts.map +1 -0
- package/dist/model-failure.js +253 -0
- package/dist/model-failure.js.map +1 -0
- package/dist/model-fallback.d.ts +18 -0
- package/dist/model-fallback.d.ts.map +1 -0
- package/dist/model-fallback.js +87 -0
- package/dist/model-fallback.js.map +1 -0
- package/dist/models.d.ts +20 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +55 -0
- package/dist/models.js.map +1 -0
- package/dist/openai-compatible.d.ts +87 -0
- package/dist/openai-compatible.d.ts.map +1 -0
- package/dist/openai-compatible.js +368 -0
- package/dist/openai-compatible.js.map +1 -0
- package/dist/openai-engine.d.ts +18 -0
- package/dist/openai-engine.d.ts.map +1 -0
- package/dist/openai-engine.js +515 -0
- package/dist/openai-engine.js.map +1 -0
- package/dist/openai-images.d.ts +38 -0
- package/dist/openai-images.d.ts.map +1 -0
- package/dist/openai-images.js +301 -0
- package/dist/openai-images.js.map +1 -0
- package/dist/openai-messages.d.ts +40 -0
- package/dist/openai-messages.d.ts.map +1 -0
- package/dist/openai-messages.js +135 -0
- package/dist/openai-messages.js.map +1 -0
- package/dist/openai-wire.d.ts +93 -0
- package/dist/openai-wire.d.ts.map +1 -0
- package/dist/openai-wire.js +151 -0
- package/dist/openai-wire.js.map +1 -0
- package/dist/persona/apply.d.ts +19 -0
- package/dist/persona/apply.d.ts.map +1 -0
- package/dist/persona/apply.js +98 -0
- package/dist/persona/apply.js.map +1 -0
- package/dist/persona/builtins.d.ts +3 -0
- package/dist/persona/builtins.d.ts.map +1 -0
- package/dist/persona/builtins.js +180 -0
- package/dist/persona/builtins.js.map +1 -0
- package/dist/persona/decorator.d.ts +4 -0
- package/dist/persona/decorator.d.ts.map +1 -0
- package/dist/persona/decorator.js +112 -0
- package/dist/persona/decorator.js.map +1 -0
- package/dist/persona/files.d.ts +20 -0
- package/dist/persona/files.d.ts.map +1 -0
- package/dist/persona/files.js +84 -0
- package/dist/persona/files.js.map +1 -0
- package/dist/persona/ids.d.ts +9 -0
- package/dist/persona/ids.d.ts.map +1 -0
- package/dist/persona/ids.js +11 -0
- package/dist/persona/ids.js.map +1 -0
- package/dist/persona/registry.d.ts +12 -0
- package/dist/persona/registry.d.ts.map +1 -0
- package/dist/persona/registry.js +54 -0
- package/dist/persona/registry.js.map +1 -0
- package/dist/persona/runtime.d.ts +23 -0
- package/dist/persona/runtime.d.ts.map +1 -0
- package/dist/persona/runtime.js +32 -0
- package/dist/persona/runtime.js.map +1 -0
- package/dist/persona/schema.d.ts +27 -0
- package/dist/persona/schema.d.ts.map +1 -0
- package/dist/persona/schema.js +165 -0
- package/dist/persona/schema.js.map +1 -0
- package/dist/persona/types.d.ts +38 -0
- package/dist/persona/types.d.ts.map +1 -0
- package/dist/persona/types.js +2 -0
- package/dist/persona/types.js.map +1 -0
- package/dist/pricing.d.ts +40 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +70 -0
- package/dist/pricing.js.map +1 -0
- package/dist/quota-park.d.ts +53 -0
- package/dist/quota-park.d.ts.map +1 -0
- package/dist/quota-park.js +135 -0
- package/dist/quota-park.js.map +1 -0
- package/dist/rate-pause.d.ts +28 -0
- package/dist/rate-pause.d.ts.map +1 -0
- package/dist/rate-pause.js +72 -0
- package/dist/rate-pause.js.map +1 -0
- package/dist/registry.d.ts +142 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +471 -0
- package/dist/registry.js.map +1 -0
- package/dist/responses.d.ts +5 -0
- package/dist/responses.d.ts.map +1 -0
- package/dist/responses.js +290 -0
- package/dist/responses.js.map +1 -0
- package/dist/retry-after.d.ts +13 -0
- package/dist/retry-after.d.ts.map +1 -0
- package/dist/retry-after.js +64 -0
- package/dist/retry-after.js.map +1 -0
- package/dist/retry-ladder.d.ts +176 -0
- package/dist/retry-ladder.d.ts.map +1 -0
- package/dist/retry-ladder.js +664 -0
- package/dist/retry-ladder.js.map +1 -0
- package/dist/split-inband-thinking.d.ts +35 -0
- package/dist/split-inband-thinking.d.ts.map +1 -0
- package/dist/split-inband-thinking.js +117 -0
- package/dist/split-inband-thinking.js.map +1 -0
- package/dist/stream-idle.d.ts +97 -0
- package/dist/stream-idle.d.ts.map +1 -0
- package/dist/stream-idle.js +127 -0
- package/dist/stream-idle.js.map +1 -0
- package/dist/tool-call-ids.d.ts +16 -0
- package/dist/tool-call-ids.d.ts.map +1 -0
- package/dist/tool-call-ids.js +36 -0
- package/dist/tool-call-ids.js.map +1 -0
- package/package.json +32 -3
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Validate + write one persona definition as `<dir>/<id>.json` (create or
|
|
2
|
+
* update — the file is keyed by the definition's OWN id). Returns the
|
|
3
|
+
* written id, or the validator's per-field errors with NOTHING on disk. */
|
|
4
|
+
export declare function savePersonaDefinition(dir: string, definition: unknown): Promise<{
|
|
5
|
+
ok: true;
|
|
6
|
+
id: string;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
errors: string[];
|
|
10
|
+
}>;
|
|
11
|
+
/** Delete `<dir>/<id>.json`. True iff the file existed and the delete
|
|
12
|
+
* succeeded; a missing file (or a traversal-shaped id — see PERSONA_ID_RE)
|
|
13
|
+
* is false, never an error. */
|
|
14
|
+
export declare function deletePersonaDefinition(dir: string, id: string): Promise<boolean>;
|
|
15
|
+
/** The tier-origin scan personaList needs: the set of PARSED persona ids in
|
|
16
|
+
* one directory (same keying rule as the registry reader — an id, not the
|
|
17
|
+
* filename). A missing dir is the empty set; a non-.json or unparsable file
|
|
18
|
+
* skips (the registry reader already reports those as its own errors). */
|
|
19
|
+
export declare function personaIdsInDir(dir: string | undefined): Promise<Set<string>>;
|
|
20
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/persona/files.ts"],"names":[],"mappings":"AA0BA;;4EAE4E;AAC5E,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CASrE;AAED;;gCAEgC;AAChC,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvF;AAED;;;2EAG2E;AAC3E,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAsBnF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// packages/providers/src/persona/files.ts
|
|
2
|
+
// SDD 2026-08-23 persona Task 5 — the global-persona CRUD file helpers (spec
|
|
3
|
+
// §7: same package as loadPersonaRegistry, the write/delete halves of the
|
|
4
|
+
// seam the reader owns). One write discipline: validate FIRST (a refused
|
|
5
|
+
// definition never touches disk), then the house atomic write (tmp+rename,
|
|
6
|
+
// 0600 — the same posture as the global settings / providers.json writers).
|
|
7
|
+
// The ops layer (cli settings-ops personaSave/personaDelete) owns the
|
|
8
|
+
// tier-collision rules (builtin/workspace ids refuse) — these helpers are
|
|
9
|
+
// pure fs: they neither know nor check the other tiers.
|
|
10
|
+
import { mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { validatePersonaDefinition } from "./schema.js";
|
|
13
|
+
/** The persona id grammar (schema.ts ID_RE, re-declared because schema keeps
|
|
14
|
+
* it private): kebab-case, no dots or slashes. deletePersonaDefinition takes
|
|
15
|
+
* a WIRE id — this guard is what keeps a traversal-shaped id ("../x") away
|
|
16
|
+
* from path resolution. */
|
|
17
|
+
const PERSONA_ID_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
18
|
+
/** The itemized form of validatePersonaDefinition's joined error string —
|
|
19
|
+
* the wire personaSave reply's `errors[]` shape (each entry field-path
|
|
20
|
+
* prefixed; the settings form matches them back to its rows). */
|
|
21
|
+
function splitErrors(joined) {
|
|
22
|
+
return joined.split("; ");
|
|
23
|
+
}
|
|
24
|
+
/** Validate + write one persona definition as `<dir>/<id>.json` (create or
|
|
25
|
+
* update — the file is keyed by the definition's OWN id). Returns the
|
|
26
|
+
* written id, or the validator's per-field errors with NOTHING on disk. */
|
|
27
|
+
export async function savePersonaDefinition(dir, definition) {
|
|
28
|
+
const v = validatePersonaDefinition(definition);
|
|
29
|
+
if (!v.ok)
|
|
30
|
+
return { ok: false, errors: splitErrors(v.error) };
|
|
31
|
+
await mkdir(dir, { recursive: true });
|
|
32
|
+
const path = join(dir, `${v.persona.id}.json`);
|
|
33
|
+
const tmp = `${path}.tmp-${process.pid}`;
|
|
34
|
+
await writeFile(tmp, `${JSON.stringify(v.persona, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
35
|
+
await rename(tmp, path);
|
|
36
|
+
return { ok: true, id: v.persona.id };
|
|
37
|
+
}
|
|
38
|
+
/** Delete `<dir>/<id>.json`. True iff the file existed and the delete
|
|
39
|
+
* succeeded; a missing file (or a traversal-shaped id — see PERSONA_ID_RE)
|
|
40
|
+
* is false, never an error. */
|
|
41
|
+
export async function deletePersonaDefinition(dir, id) {
|
|
42
|
+
if (!PERSONA_ID_RE.test(id))
|
|
43
|
+
return false;
|
|
44
|
+
try {
|
|
45
|
+
await rm(join(dir, `${id}.json`));
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false; // ENOENT (or any fs refusal) — nothing was deleted
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** The tier-origin scan personaList needs: the set of PARSED persona ids in
|
|
53
|
+
* one directory (same keying rule as the registry reader — an id, not the
|
|
54
|
+
* filename). A missing dir is the empty set; a non-.json or unparsable file
|
|
55
|
+
* skips (the registry reader already reports those as its own errors). */
|
|
56
|
+
export async function personaIdsInDir(dir) {
|
|
57
|
+
const ids = new Set();
|
|
58
|
+
if (dir === undefined)
|
|
59
|
+
return ids;
|
|
60
|
+
let names;
|
|
61
|
+
try {
|
|
62
|
+
names = await readdir(dir);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return ids;
|
|
66
|
+
}
|
|
67
|
+
for (const name of names.sort()) {
|
|
68
|
+
if (!name.endsWith(".json"))
|
|
69
|
+
continue;
|
|
70
|
+
try {
|
|
71
|
+
const raw = JSON.parse(await readFile(join(dir, name), "utf8"));
|
|
72
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
73
|
+
const id = raw["id"];
|
|
74
|
+
if (typeof id === "string" && id !== "")
|
|
75
|
+
ids.add(id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// skip — the registry reader is the error-reporting site
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return ids;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/persona/files.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,sEAAsE;AACtE,0EAA0E;AAC1E,wDAAwD;AACxD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD;;;4BAG4B;AAC5B,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD;;kEAEkE;AAClE,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;4EAE4E;AAC5E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAW,EACX,UAAmB;IAEnB,MAAM,CAAC,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9D,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnG,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;;gCAEgC;AAChC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,GAAW,EAAE,EAAU;IACnE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,CAAC,mDAAmD;IACnE,CAAC;AACH,CAAC;AAED;;;2EAG2E;AAC3E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAuB;IAC3D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YACzE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnE,MAAM,EAAE,GAAI,GAA+B,CAAC,IAAI,CAAC,CAAC;gBAClD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,EAAE;oBAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const PERSONA_IDS: {
|
|
2
|
+
readonly ANTHROPIC_CLI: "anthropic-cli";
|
|
3
|
+
readonly OPENAI_RESPONSES: "openai-responses";
|
|
4
|
+
readonly CURSOR: "cursor";
|
|
5
|
+
readonly MULTI_WIRE: "multi-wire";
|
|
6
|
+
readonly DEEPSEEK_NATIVE: "deepseek-native";
|
|
7
|
+
};
|
|
8
|
+
export type PersonaId = (typeof PERSONA_IDS)[keyof typeof PERSONA_IDS];
|
|
9
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/persona/ids.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW;;;;;;CAMd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Persona IDs — the single source of truth for functional identifiers.
|
|
2
|
+
// Both builtins and tests reference these values; cleanup scripts skip this file.
|
|
3
|
+
// IMPORTANT: these must be valid kebab-case (no spaces).
|
|
4
|
+
export const PERSONA_IDS = {
|
|
5
|
+
ANTHROPIC_CLI: "anthropic-cli",
|
|
6
|
+
OPENAI_RESPONSES: "openai-responses",
|
|
7
|
+
CURSOR: "cursor",
|
|
8
|
+
MULTI_WIRE: "multi-wire",
|
|
9
|
+
DEEPSEEK_NATIVE: "deepseek-native",
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/persona/ids.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kFAAkF;AAClF,yDAAyD;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,iBAAiB;CAC1B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PersonaDefinition } from "./types.js";
|
|
2
|
+
export interface PersonaRegistry {
|
|
3
|
+
readonly personas: readonly PersonaDefinition[];
|
|
4
|
+
readonly errors: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
/** 内置 → global(~/.wudao/personas) → workspace(<ws>/.wudao/personas),同 id 后者胜。 */
|
|
7
|
+
export declare function loadPersonaRegistry(dirs: {
|
|
8
|
+
readonly globalDir?: string;
|
|
9
|
+
readonly workspaceDir?: string;
|
|
10
|
+
}): Promise<PersonaRegistry>;
|
|
11
|
+
export declare function lookupPersona(registry: PersonaRegistry, id: string): PersonaDefinition | undefined;
|
|
12
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/persona/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AA0BD,iFAAiF;AACjF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAUzI;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAElG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// packages/providers/src/persona/registry.ts
|
|
2
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { validatePersonaDefinition } from "./schema.js";
|
|
5
|
+
import { BUILTIN_PERSONAS } from "./builtins.js";
|
|
6
|
+
async function readDirPersonas(dir, label, errors) {
|
|
7
|
+
const out = new Map();
|
|
8
|
+
if (dir === undefined)
|
|
9
|
+
return out;
|
|
10
|
+
let names;
|
|
11
|
+
try {
|
|
12
|
+
names = await readdir(dir);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return out; // 目录不存在 = 该层级为空,不是错误
|
|
16
|
+
}
|
|
17
|
+
for (const name of names.sort()) {
|
|
18
|
+
if (!name.endsWith(".json"))
|
|
19
|
+
continue;
|
|
20
|
+
const path = join(dir, name);
|
|
21
|
+
try {
|
|
22
|
+
const raw = JSON.parse(await readFile(path, "utf8"));
|
|
23
|
+
const v = validatePersonaDefinition(raw);
|
|
24
|
+
if (!v.ok) {
|
|
25
|
+
errors.push(`${label}/${name}: ${v.error}`);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
out.set(v.persona.id, { persona: v.persona, filename: name });
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
errors.push(`${label}/${name}: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
/** 内置 → global(~/.wudao/personas) → workspace(<ws>/.wudao/personas),同 id 后者胜。 */
|
|
37
|
+
export async function loadPersonaRegistry(dirs) {
|
|
38
|
+
const errors = [];
|
|
39
|
+
const merged = new Map();
|
|
40
|
+
for (const p of BUILTIN_PERSONAS)
|
|
41
|
+
merged.set(p.id, { persona: p, filename: "" });
|
|
42
|
+
for (const [id, value] of (await readDirPersonas(dirs.globalDir, "global", errors)).entries())
|
|
43
|
+
merged.set(id, value);
|
|
44
|
+
for (const [id, value] of (await readDirPersonas(dirs.workspaceDir, "workspace", errors)).entries())
|
|
45
|
+
merged.set(id, value);
|
|
46
|
+
const personas = [...merged.values()]
|
|
47
|
+
.sort((a, b) => a.filename.localeCompare(b.filename))
|
|
48
|
+
.map((v) => v.persona);
|
|
49
|
+
return { personas, errors };
|
|
50
|
+
}
|
|
51
|
+
export function lookupPersona(registry, id) {
|
|
52
|
+
return registry.personas.find((p) => p.id === id);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/persona/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LayerFlags, PersonaDefinition, ResolvedPersona } from "./types.js";
|
|
2
|
+
export interface PersonaRuntimeSlots {
|
|
3
|
+
readonly sessionId?: string;
|
|
4
|
+
readonly uuid?: () => string;
|
|
5
|
+
readonly now?: () => Date;
|
|
6
|
+
}
|
|
7
|
+
export interface PersonaRuntime {
|
|
8
|
+
current: ResolvedPersona | null;
|
|
9
|
+
readonly slots: PersonaRuntimeSlots;
|
|
10
|
+
}
|
|
11
|
+
export declare function createPersonaRuntime(initial?: ResolvedPersona | null, slots?: PersonaRuntimeSlots): PersonaRuntime;
|
|
12
|
+
export declare function resolvePersona(persona: PersonaDefinition, layers?: Partial<LayerFlags>): ResolvedPersona;
|
|
13
|
+
/** `<id>` 或 `<id>:headers[,body][,prompt]`——非空、无重复、无未知层。层列表
|
|
14
|
+
* 分隔符:`,`(WUDAO_PERSONA 既有语法)与 `+`(设置页写入的规范形态)等价。 */
|
|
15
|
+
export declare function parsePersonaSpec(spec: string): {
|
|
16
|
+
ok: true;
|
|
17
|
+
id: string;
|
|
18
|
+
layers?: Partial<LayerFlags>;
|
|
19
|
+
} | {
|
|
20
|
+
ok: false;
|
|
21
|
+
error: string;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/persona/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGjF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;CACrC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,eAAe,GAAG,IAAW,EAAE,KAAK,GAAE,mBAAwB,GAAG,cAAc,CAE5H;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,eAAe,CAExG;AAED;qDACqD;AACrD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAepI"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { effectiveLayers } from "./schema.js";
|
|
2
|
+
export function createPersonaRuntime(initial = null, slots = {}) {
|
|
3
|
+
return { current: initial, slots };
|
|
4
|
+
}
|
|
5
|
+
export function resolvePersona(persona, layers) {
|
|
6
|
+
return { definition: persona, layers: effectiveLayers(persona, layers) };
|
|
7
|
+
}
|
|
8
|
+
/** `<id>` 或 `<id>:headers[,body][,prompt]`——非空、无重复、无未知层。层列表
|
|
9
|
+
* 分隔符:`,`(WUDAO_PERSONA 既有语法)与 `+`(设置页写入的规范形态)等价。 */
|
|
10
|
+
export function parsePersonaSpec(spec) {
|
|
11
|
+
const colon = spec.indexOf(":");
|
|
12
|
+
const id = (colon === -1 ? spec : spec.slice(0, colon)).trim();
|
|
13
|
+
if (id === "")
|
|
14
|
+
return { ok: false, error: `persona id missing in "${spec}"` };
|
|
15
|
+
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(id))
|
|
16
|
+
return { ok: false, error: `persona id "${id}" is not kebab-case` };
|
|
17
|
+
if (colon === -1)
|
|
18
|
+
return { ok: true, id };
|
|
19
|
+
const parts = spec.slice(colon + 1).split(/[,+]/).map((s) => s.trim()).filter((s) => s !== "");
|
|
20
|
+
if (parts.length === 0)
|
|
21
|
+
return { ok: false, error: `empty layer list in "${spec}"` };
|
|
22
|
+
const layers = {};
|
|
23
|
+
for (const p of parts) {
|
|
24
|
+
if (p !== "headers" && p !== "body" && p !== "prompt")
|
|
25
|
+
return { ok: false, error: `unknown layer "${p}" (allowed: headers, body, prompt)` };
|
|
26
|
+
if (layers[p] !== undefined)
|
|
27
|
+
return { ok: false, error: `duplicate layer "${p}"` };
|
|
28
|
+
layers[p] = true;
|
|
29
|
+
}
|
|
30
|
+
return { ok: true, id, layers };
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/persona/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAa9C,MAAM,UAAU,oBAAoB,CAAC,UAAkC,IAAI,EAAE,QAA6B,EAAE;IAC1G,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAA0B,EAAE,MAA4B;IACrF,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;qDACqD;AACrD,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,IAAI,GAAG,EAAE,CAAC;IAC9E,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,CAAC;IAC9G,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,IAAI,GAAG,EAAE,CAAC;IACrF,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,oCAAoC,EAAE,CAAC;QAC5I,IAAI,MAAM,CAAC,CAAqB,CAAC,KAAK,SAAS;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,CAAC,GAAG,EAAE,CAAC;QACtG,MAAkC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LayerFlags, PersonaDefinition, ProtocolId } from "./types.js";
|
|
2
|
+
export declare const PROTOCOL_IDS: readonly ProtocolId[];
|
|
3
|
+
/** v1 冻结键集(spec §4 层2)。扩键 = 改本表,走评审。 */
|
|
4
|
+
export declare const BODY_WHITELIST: Readonly<Record<ProtocolId, ReadonlySet<string>>>;
|
|
5
|
+
/** Final-review I3:persona 永不控制的头——鉴权键 + hop-by-hop / 传输语义头
|
|
6
|
+
* (persona 头在适配器自带头之后 spread,工作区 JSON 若能写这些键就会
|
|
7
|
+
* 覆盖适配器自身的传输头)。ω99-69:定义下沉 header-validation.ts(单一
|
|
8
|
+
* 来源,四个消费面同一堵墙:schema 加载期拒绝、resolvePersonaHeaders 防
|
|
9
|
+
* 御性跳过、registry 保存/加载期拒行、gatewayExtraHeaders seam 跳过);
|
|
10
|
+
* 此处 re-export 保既有 import 面(registry/apply 的 ABI 零 diff),下方
|
|
11
|
+
* checkHeaderMap 消费的是同一 Set(顶部 import 即本 re-export 的源)。 */
|
|
12
|
+
export { FORBIDDEN_HEADER_KEYS } from "../header-validation.js";
|
|
13
|
+
export declare function validatePersonaDefinition(raw: unknown): {
|
|
14
|
+
ok: true;
|
|
15
|
+
persona: PersonaDefinition;
|
|
16
|
+
} | {
|
|
17
|
+
ok: false;
|
|
18
|
+
error: string;
|
|
19
|
+
};
|
|
20
|
+
/** 层集解析(spec §10.1,2026-08-23 迭代2 fix round 1):
|
|
21
|
+
* - 无限定(override 缺省或全空)→ 缺省层集 {headers:true, body:true,
|
|
22
|
+
* prompt:false} ← persona.defaultLayers(与历史逐字节一致)。
|
|
23
|
+
* - 带显式限定(override 存在且至少一键有值)→ 限定列出的是**完整启用集**
|
|
24
|
+
* (mask):未列出的层 = 关,persona.defaultLayers 不参与——
|
|
25
|
+
* `claude-code:headers` = 只启用 headers 层。 */
|
|
26
|
+
export declare function effectiveLayers(persona: PersonaDefinition, override?: Partial<LayerFlags>): LayerFlags;
|
|
27
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/persona/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAG3G,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAA8C,CAAC;AAE7F,wCAAwC;AACxC,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAI5E,CAAC;AAEF;;;;;;2DAM2D;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAwDhE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqC/H;AAED;;;;;+CAK+C;AAC/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAStG"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { FORBIDDEN_HEADER_KEYS, headerRepresentabilityError } from "../header-validation.js";
|
|
2
|
+
export const PROTOCOL_IDS = ["openai-chat", "anthropic", "responses"];
|
|
3
|
+
/** v1 冻结键集(spec §4 层2)。扩键 = 改本表,走评审。 */
|
|
4
|
+
export const BODY_WHITELIST = {
|
|
5
|
+
"openai-chat": new Set(["temperature", "top_p", "top_k", "max_tokens", "reasoning_effort", "reasoning", "stop", "metadata"]),
|
|
6
|
+
anthropic: new Set(["temperature", "top_p", "top_k", "max_tokens", "thinking", "stop_sequences", "metadata"]),
|
|
7
|
+
responses: new Set(["temperature", "top_p", "max_completion_tokens", "reasoning", "instructions", "store", "metadata"]),
|
|
8
|
+
};
|
|
9
|
+
/** Final-review I3:persona 永不控制的头——鉴权键 + hop-by-hop / 传输语义头
|
|
10
|
+
* (persona 头在适配器自带头之后 spread,工作区 JSON 若能写这些键就会
|
|
11
|
+
* 覆盖适配器自身的传输头)。ω99-69:定义下沉 header-validation.ts(单一
|
|
12
|
+
* 来源,四个消费面同一堵墙:schema 加载期拒绝、resolvePersonaHeaders 防
|
|
13
|
+
* 御性跳过、registry 保存/加载期拒行、gatewayExtraHeaders seam 跳过);
|
|
14
|
+
* 此处 re-export 保既有 import 面(registry/apply 的 ABI 零 diff),下方
|
|
15
|
+
* checkHeaderMap 消费的是同一 Set(顶部 import 即本 re-export 的源)。 */
|
|
16
|
+
export { FORBIDDEN_HEADER_KEYS } from "../header-validation.js";
|
|
17
|
+
const SLOT_RE = /^\{\{(sessionId|uuid|iso8601)\}\}$/;
|
|
18
|
+
const ID_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
19
|
+
function isRecord(v) {
|
|
20
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
21
|
+
}
|
|
22
|
+
function checkHeaderMap(where, raw, errors) {
|
|
23
|
+
if (!isRecord(raw)) {
|
|
24
|
+
errors.push(`${where}: header map must be an object`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
28
|
+
if (FORBIDDEN_HEADER_KEYS.has(k.toLowerCase())) {
|
|
29
|
+
errors.push(`${where}.${k}: "${k.toLowerCase()}" is a forbidden persona header (auth/transport-control — the adapter owns it)`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (typeof v !== "string") {
|
|
33
|
+
errors.push(`${where}.${k}: header value must be a string`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
// ω99-50:fetch 可表示性(加载期红)。换行值/非法字段名/非字节字符在
|
|
37
|
+
// schema 期即拒——否则失败发生在请求时刻(undici 匿名 TypeError,不指名
|
|
38
|
+
// 哪个 persona 哪个 header)。与 applyWirePersona 的 assertValidHeaders
|
|
39
|
+
// 消费同一探针(header-validation.ts 单一来源);savePersonaDefinition
|
|
40
|
+
// 走本校验器,保存期即红随之而来。
|
|
41
|
+
const rep = headerRepresentabilityError(k, v);
|
|
42
|
+
if (rep !== null) {
|
|
43
|
+
errors.push(`${where}.${k}: cannot ride the wire — ${rep}`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
for (const part of v.split(/(\{\{[^}]*\}\})/).filter((s) => s.startsWith("{{"))) {
|
|
47
|
+
if (!SLOT_RE.test(part))
|
|
48
|
+
errors.push(`${where}.${k}: unknown template slot ${part} (allowed: sessionId|uuid|iso8601)`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function checkBodyOverlay(where, protocol, raw, errors) {
|
|
53
|
+
if (!isRecord(raw)) {
|
|
54
|
+
errors.push(`${where}: body overlay must be an object`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const allow = BODY_WHITELIST[protocol];
|
|
58
|
+
for (const k of Object.keys(raw)) {
|
|
59
|
+
if (!allow.has(k))
|
|
60
|
+
errors.push(`${where}.${k}: key not in the ${protocol} body whitelist`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function checkPrompt(raw, errors) {
|
|
64
|
+
if (raw === undefined)
|
|
65
|
+
return;
|
|
66
|
+
if (!isRecord(raw)) {
|
|
67
|
+
errors.push("prompt: must be an object");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
for (const k of Object.keys(raw))
|
|
71
|
+
if (k !== "system" && k !== "toolNameMap")
|
|
72
|
+
errors.push(`prompt.${k}: unknown key`);
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
if (raw.system !== undefined) {
|
|
75
|
+
if (!isRecord(raw.system) || (raw.system.mode !== "snapshot" && raw.system.mode !== "prefix") || typeof raw.system.text !== "string") {
|
|
76
|
+
errors.push("prompt.system: {mode: snapshot|prefix, text: string} required");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (raw.toolNameMap !== undefined) {
|
|
80
|
+
if (!isRecord(raw.toolNameMap)) {
|
|
81
|
+
errors.push("prompt.toolNameMap: must be an object");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
for (const [from, to] of Object.entries(raw.toolNameMap)) {
|
|
85
|
+
if (typeof to !== "string" || to === "" || to === from)
|
|
86
|
+
errors.push(`prompt.toolNameMap.${from}: must map to a different non-empty name`);
|
|
87
|
+
if (typeof to === "string") {
|
|
88
|
+
if (seen.has(to))
|
|
89
|
+
errors.push(`prompt.toolNameMap.${from}: display name "${to}" is already used (reverse map would be ambiguous)`);
|
|
90
|
+
seen.add(to);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export function validatePersonaDefinition(raw) {
|
|
96
|
+
const errors = [];
|
|
97
|
+
if (!isRecord(raw))
|
|
98
|
+
return { ok: false, error: "persona: must be an object" };
|
|
99
|
+
const allowed = new Set(["id", "displayName", "source", "defaultLayers", "headers", "body", "prompt", "confidence"]);
|
|
100
|
+
for (const k of Object.keys(raw))
|
|
101
|
+
if (!allowed.has(k))
|
|
102
|
+
errors.push(`unknown key "${k}"`);
|
|
103
|
+
if (typeof raw.id !== "string" || !ID_RE.test(raw.id))
|
|
104
|
+
errors.push("id: kebab-case required");
|
|
105
|
+
if (typeof raw.displayName !== "string" || raw.displayName === "")
|
|
106
|
+
errors.push("displayName: non-empty string required");
|
|
107
|
+
if (!isRecord(raw.source) || (raw.source.kind !== "workspace-source" && raw.source.kind !== "external-research")
|
|
108
|
+
|| typeof raw.source.provenance !== "string" || raw.source.provenance === ""
|
|
109
|
+
|| typeof raw.source.pinnedVersion !== "string" || raw.source.pinnedVersion === "") {
|
|
110
|
+
errors.push("source: {kind, provenance, pinnedVersion} all required (provenance/pinnedVersion non-empty)");
|
|
111
|
+
}
|
|
112
|
+
if (raw.confidence !== undefined && raw.confidence !== "byte-verified" && raw.confidence !== "community-reverse-engineered") {
|
|
113
|
+
errors.push("confidence: byte-verified | community-reverse-engineered");
|
|
114
|
+
}
|
|
115
|
+
if (raw.defaultLayers !== undefined) {
|
|
116
|
+
if (!isRecord(raw.defaultLayers))
|
|
117
|
+
errors.push("defaultLayers: must be an object");
|
|
118
|
+
else
|
|
119
|
+
for (const [k, v] of Object.entries(raw.defaultLayers)) {
|
|
120
|
+
if (k !== "headers" && k !== "body" && k !== "prompt")
|
|
121
|
+
errors.push(`defaultLayers.${k}: unknown layer`);
|
|
122
|
+
else if (typeof v !== "boolean")
|
|
123
|
+
errors.push(`defaultLayers.${k}: boolean required`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!isRecord(raw.headers))
|
|
127
|
+
errors.push("headers: object required (may be empty)");
|
|
128
|
+
else
|
|
129
|
+
for (const [proto, map] of Object.entries(raw.headers)) {
|
|
130
|
+
if (!PROTOCOL_IDS.includes(proto))
|
|
131
|
+
errors.push(`headers.${proto}: unknown protocol`);
|
|
132
|
+
else
|
|
133
|
+
checkHeaderMap(`headers.${proto}`, map, errors);
|
|
134
|
+
}
|
|
135
|
+
if (raw.body !== undefined) {
|
|
136
|
+
if (!isRecord(raw.body))
|
|
137
|
+
errors.push("body: must be an object");
|
|
138
|
+
else
|
|
139
|
+
for (const [proto, overlay] of Object.entries(raw.body)) {
|
|
140
|
+
if (!PROTOCOL_IDS.includes(proto))
|
|
141
|
+
errors.push(`body.${proto}: unknown protocol`);
|
|
142
|
+
else
|
|
143
|
+
checkBodyOverlay(`body.${proto}`, proto, overlay, errors);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
checkPrompt(raw.prompt, errors);
|
|
147
|
+
if (errors.length > 0)
|
|
148
|
+
return { ok: false, error: errors.join("; ") };
|
|
149
|
+
return { ok: true, persona: raw };
|
|
150
|
+
}
|
|
151
|
+
/** 层集解析(spec §10.1,2026-08-23 迭代2 fix round 1):
|
|
152
|
+
* - 无限定(override 缺省或全空)→ 缺省层集 {headers:true, body:true,
|
|
153
|
+
* prompt:false} ← persona.defaultLayers(与历史逐字节一致)。
|
|
154
|
+
* - 带显式限定(override 存在且至少一键有值)→ 限定列出的是**完整启用集**
|
|
155
|
+
* (mask):未列出的层 = 关,persona.defaultLayers 不参与——
|
|
156
|
+
* `claude-code:headers` = 只启用 headers 层。 */
|
|
157
|
+
export function effectiveLayers(persona, override) {
|
|
158
|
+
if (override !== undefined &&
|
|
159
|
+
(override.headers !== undefined || override.body !== undefined || override.prompt !== undefined)) {
|
|
160
|
+
return { headers: override.headers === true, body: override.body === true, prompt: override.prompt === true };
|
|
161
|
+
}
|
|
162
|
+
const d = { headers: true, body: true, prompt: false, ...(persona.defaultLayers ?? {}) };
|
|
163
|
+
return d;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/persona/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE7F,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AAE7F,wCAAwC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAsD;IAC/E,aAAa,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5H,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;IAC7G,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;CACxH,CAAC;AAEF;;;;;;2DAM2D;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,MAAM,OAAO,GAAG,oCAAoC,CAAC;AACrD,MAAM,KAAK,GAAG,0BAA0B,CAAC;AAEzC,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,GAAY,EAAE,MAAgB;IACnE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,gCAAgC,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACtF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,gFAAgF,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9L,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACrG,2CAA2C;QAC3C,kDAAkD;QAClD,gEAAgE;QAChE,0DAA0D;QAC1D,mBAAmB;QACnB,MAAM,GAAG,GAAG,2BAA2B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC5F,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAChF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,2BAA2B,IAAI,oCAAoC,CAAC,CAAC;QACzH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,QAAoB,EAAE,GAAY,EAAE,MAAgB;IAC3F,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACxF,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,oBAAoB,QAAQ,iBAAiB,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,MAAgB;IACjD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACzE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,aAAa;YAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IACrH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrI,MAAM,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACjG,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACzD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,0CAA0C,CAAC,CAAC;YAC1I,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,IAAI,mBAAmB,EAAE,oDAAoD,CAAC,CAAC;gBACnI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,GAAY;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IACrH,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzF,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC9F,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,IAAI,GAAG,CAAC,WAAW,KAAK,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACzH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,mBAAmB,CAAC;WAC3G,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,EAAE;WACzE,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,EAAE,EAAE,CAAC;QACrF,MAAM,CAAC,IAAI,CAAC,6FAA6F,CAAC,CAAC;IAC7G,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,GAAG,CAAC,UAAU,KAAK,eAAe,IAAI,GAAG,CAAC,UAAU,KAAK,8BAA8B,EAAE,CAAC;QAC5H,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;;YAC7E,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5D,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,QAAQ;oBAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;qBACnG,IAAI,OAAO,CAAC,KAAK,SAAS;oBAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;YACvF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;;QAC9E,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAmB,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,oBAAoB,CAAC,CAAC;;gBAC9F,cAAc,CAAC,WAAW,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;;YAC3D,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7D,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAmB,CAAC;oBAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,oBAAoB,CAAC,CAAC;;oBAC3F,gBAAgB,CAAC,QAAQ,KAAK,EAAE,EAAE,KAAmB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/E,CAAC;IACH,CAAC;IACD,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACtE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAmC,EAAE,CAAC;AACpE,CAAC;AAED;;;;;+CAK+C;AAC/C,MAAM,UAAU,eAAe,CAAC,OAA0B,EAAE,QAA8B;IACxF,IACE,QAAQ,KAAK,SAAS;QACtB,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,EAChG,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;IAChH,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,CAAC;IACzF,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type ProtocolId = "openai-chat" | "anthropic" | "responses";
|
|
2
|
+
export interface LayerFlags {
|
|
3
|
+
readonly headers: boolean;
|
|
4
|
+
readonly body: boolean;
|
|
5
|
+
readonly prompt: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface PersonaSource {
|
|
8
|
+
readonly kind: "workspace-source" | "external-research";
|
|
9
|
+
readonly provenance: string;
|
|
10
|
+
readonly pinnedVersion: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SystemStyle {
|
|
13
|
+
readonly mode: "snapshot" | "prefix";
|
|
14
|
+
readonly text: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PromptStyle {
|
|
17
|
+
readonly system?: SystemStyle;
|
|
18
|
+
/** 我们的工具名 → 客户端显示名。decorator 双向映射(出向改名,入向逆映射 tool_calls)。 */
|
|
19
|
+
readonly toolNameMap?: Readonly<Record<string, string>>;
|
|
20
|
+
}
|
|
21
|
+
/** 声明式请求体叠加——键必须 ⊆ 该协议白名单(schema.ts),persona 是数据不是代码。 */
|
|
22
|
+
export type BodyStyleOverlay = Readonly<Record<string, unknown>>;
|
|
23
|
+
export interface PersonaDefinition {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly displayName: string;
|
|
26
|
+
readonly source: PersonaSource;
|
|
27
|
+
/** 未提供时默认 { headers: true, body: true, prompt: false }。 */
|
|
28
|
+
readonly defaultLayers?: Partial<LayerFlags>;
|
|
29
|
+
readonly headers: Partial<Record<ProtocolId, Readonly<Record<string, string>>>>;
|
|
30
|
+
readonly body?: Partial<Record<ProtocolId, BodyStyleOverlay>>;
|
|
31
|
+
readonly prompt?: PromptStyle;
|
|
32
|
+
readonly confidence?: "byte-verified" | "community-reverse-engineered";
|
|
33
|
+
}
|
|
34
|
+
export interface ResolvedPersona {
|
|
35
|
+
readonly definition: PersonaDefinition;
|
|
36
|
+
readonly layers: LayerFlags;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persona/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,GAAG,mBAAmB,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,GAAG,8BAA8B,CAAC;CACxE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/persona/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type CachePricing } from "@wudao-org/core";
|
|
2
|
+
/** 一条目录价格(per-M-USD)。input/cacheRead 是 ratio 的必需面;output/
|
|
3
|
+
* cacheWrite 可选(/cost 全账面用,缺省按 0 计)。 */
|
|
4
|
+
export interface ModelPrices {
|
|
5
|
+
/** cache miss 输入价(重读的 DeepSeek 形落点)。 */
|
|
6
|
+
readonly inputPerM: number;
|
|
7
|
+
/** 缓存命中价(每请求幸存前缀的持续成本)。 */
|
|
8
|
+
readonly cacheReadPerM: number;
|
|
9
|
+
readonly outputPerM?: number;
|
|
10
|
+
/** 独立缓存写价(OpenAI/Anthropic 形;缺省 = 无独立写价)。 */
|
|
11
|
+
readonly cacheWritePerM?: number;
|
|
12
|
+
}
|
|
13
|
+
/** registry/目录行的 fail-closed 形状校验:必需面在场且 finite ≥ 0,可选面
|
|
14
|
+
* 在场时同样。坏行拒收(fail-visible),绝不猜成 rate。 */
|
|
15
|
+
export declare function isModelPrices(v: unknown): v is ModelPrices;
|
|
16
|
+
/** 一档推导输入(与 CLI cost.ts 的 PriceEntry 结构同形——CLI 把已解析的 env
|
|
17
|
+
* 行原样递进来,不重造解析器)。 */
|
|
18
|
+
export interface PriceSource {
|
|
19
|
+
readonly inputPerM: number;
|
|
20
|
+
readonly cacheReadPerM: number;
|
|
21
|
+
readonly cacheWritePerM?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 推导压缩经济学的定价事实。优先级 catalog > env > 保守缺省;每一档的来源
|
|
25
|
+
* 都类型化在 ratioSource 上("default" = 价目未知,决策面板可见)。
|
|
26
|
+
* 纯函数。
|
|
27
|
+
*/
|
|
28
|
+
export declare function deriveCachePricing(input: {
|
|
29
|
+
/** registry 目录 pin(effectiveProfiles 的 models[].prices)。 */
|
|
30
|
+
readonly catalog?: ModelPrices;
|
|
31
|
+
/** WUDAO_PRICE_<MODEL> env 行(调用方解析后递入)。 */
|
|
32
|
+
readonly env?: PriceSource;
|
|
33
|
+
}): CachePricing;
|
|
34
|
+
/** 在一个 effective profile 的目录里按模型名找价格 pin(精确名;目录缺该
|
|
35
|
+
* 模型 = undefined)。纯。 */
|
|
36
|
+
export declare function catalogPricesFor(models: readonly {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly prices?: ModelPrices;
|
|
39
|
+
}[] | undefined, model: string): ModelPrices | undefined;
|
|
40
|
+
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAeA,OAAO,EAAkC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpF;wCACwC;AACxC,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;yCACyC;AACzC,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,WAAW,CAQ1D;AAED;qBACqB;AACrB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAmBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC;CAC5B,GAAG,YAAY,CAUf;AAED;wBACwB;AACxB,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,GAAG,SAAS,EACvF,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,SAAS,CAIzB"}
|