dsh-llm-fallbacks 0.1.3 → 0.1.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 +4 -2
- package/README.zh-CN.md +4 -2
- package/dist/client/fallbacks-store.d.ts +34 -2
- package/dist/client/index.js +464 -335
- package/dist/client/locales.d.ts +14 -4
- package/dist/gateway.d.ts +75 -23
- package/dist/index.d.ts +13 -3
- package/dist/index.js +243 -5
- package/dist/seeds.d.ts +141 -0
- package/package.json +2 -1
package/dist/seeds.d.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role-seeds domain module (plan fallbacks-role-seeds Task 1).
|
|
3
|
+
*
|
|
4
|
+
* A companion plugin declares `[{ id, persona }]` seeds; this module
|
|
5
|
+
* validates each id AS DECLARED (`ROLE_ID_PATTERN`, reserved `inherit`),
|
|
6
|
+
* merges the declarations into the role taxonomy with immutable-id /
|
|
7
|
+
* override / revert semantics, and writes through a narrow IO seam
|
|
8
|
+
* (`SeedsIo`). It is free of `@deepseek-ai/*` value imports (bundle
|
|
9
|
+
* purity gate) — the client may type-only import from here.
|
|
10
|
+
*
|
|
11
|
+
* State model (spec §9.2) — two stores, strictly separated:
|
|
12
|
+
* 1. operator config rows (persisted; a seeded role is a plain
|
|
13
|
+
* `roles.list` row `{ id, persona }`), and
|
|
14
|
+
* 2. an in-memory per-apply seed registry (`Map<id, seedPersona>`),
|
|
15
|
+
* declare = replacement (the batch is the companion's full current set).
|
|
16
|
+
* `seeded` / `personaOverridden` are DERIVED at read time, never stored —
|
|
17
|
+
* a config round-trip cannot orphan an override (AC-3).
|
|
18
|
+
*
|
|
19
|
+
* Materialization (spec §9.2): append `{ id, persona }` (two keys only,
|
|
20
|
+
* R4) / attach row untouched / at-default tracking / override preserved +
|
|
21
|
+
* `'persona-source'` conflict / omitted id drops from the registry while
|
|
22
|
+
* the row stays (R2). No delta → no settings write (idempotent, AC-1).
|
|
23
|
+
* Compute → write → commit registry: a failed write throws and leaves the
|
|
24
|
+
* registry unchanged (retry-safe).
|
|
25
|
+
*
|
|
26
|
+
* @module dsh-llm-fallbacks/seeds
|
|
27
|
+
*/
|
|
28
|
+
import { type FallbackStrategy, type FallbacksConfig, type FallbacksConfigLogger, type FallbacksRoles } from './config.ts';
|
|
29
|
+
/** A seed declaration from a companion plugin (spec §9.1). */
|
|
30
|
+
export interface SeedDeclaration {
|
|
31
|
+
id: string;
|
|
32
|
+
persona: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Why one declared id was skipped (spec §9.1). Per-id skip + warn, never
|
|
36
|
+
* coercion — valid siblings in the same batch still apply (AC-5).
|
|
37
|
+
*/
|
|
38
|
+
export type SeedSkipReason = 'invalid-id' | 'reserved-id' | 'duplicate-in-batch';
|
|
39
|
+
/**
|
|
40
|
+
* A loud, non-destructive conflict (AC-2): never silently duplicated or
|
|
41
|
+
* merged.
|
|
42
|
+
*/
|
|
43
|
+
export interface SeedConflict {
|
|
44
|
+
id: string;
|
|
45
|
+
/** Existing row persona differs from the seed default — operator override retained, never overwritten. */
|
|
46
|
+
kind: 'persona-source';
|
|
47
|
+
}
|
|
48
|
+
/** Structured result of one `declare()` (spec §9.1) — the readable status channel. */
|
|
49
|
+
export interface SeedDeclareOutcome {
|
|
50
|
+
applied: string[];
|
|
51
|
+
skipped: Array<{
|
|
52
|
+
id: string;
|
|
53
|
+
reason: SeedSkipReason;
|
|
54
|
+
}>;
|
|
55
|
+
conflicts: SeedConflict[];
|
|
56
|
+
}
|
|
57
|
+
/** Effective role readback entry (spec §9.1) — `chain`/`fallback` passthrough (R4). */
|
|
58
|
+
export interface EffectiveRole {
|
|
59
|
+
/** The config row id (raw declared form). */
|
|
60
|
+
id: string;
|
|
61
|
+
/** Effective row persona. */
|
|
62
|
+
persona: string;
|
|
63
|
+
/** Passthrough — never touched by seeds (R4). */
|
|
64
|
+
chain?: string[];
|
|
65
|
+
/** Passthrough — never touched by seeds (R4). */
|
|
66
|
+
fallback?: FallbackStrategy;
|
|
67
|
+
/** Id is in the live declaration set (trimmed row-id match). */
|
|
68
|
+
seeded: boolean;
|
|
69
|
+
/** `seeded` && row persona !== current seed default. */
|
|
70
|
+
personaOverridden: boolean;
|
|
71
|
+
/** Present iff seeded. */
|
|
72
|
+
seedPersona?: string;
|
|
73
|
+
}
|
|
74
|
+
/** Service readback (b): effective taxonomy with seed annotations. */
|
|
75
|
+
export interface EffectiveRolesReadback {
|
|
76
|
+
roles: EffectiveRole[];
|
|
77
|
+
}
|
|
78
|
+
export type SeedRevertFailReason = 'not-seeded' | 'row-absent' | 'settings-unavailable';
|
|
79
|
+
export interface SeedRevertOutcome {
|
|
80
|
+
reverted: boolean;
|
|
81
|
+
/** Restored current seed default — present iff reverted. */
|
|
82
|
+
persona?: string;
|
|
83
|
+
reason?: SeedRevertFailReason;
|
|
84
|
+
}
|
|
85
|
+
/** Gateway wire entry (card badge state, spec §9.4). */
|
|
86
|
+
export interface SeedsWireStatus {
|
|
87
|
+
id: string;
|
|
88
|
+
overridden: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The narrow IO seam this module writes through — keeps `src/seeds.ts`
|
|
92
|
+
* free of `@deepseek-ai/*` value imports (bundle purity gate).
|
|
93
|
+
*/
|
|
94
|
+
export interface SeedsIo {
|
|
95
|
+
/** Fresh composed config read (the same source the gateway reads). */
|
|
96
|
+
read(): FallbacksConfig;
|
|
97
|
+
/** Persist a full `{ list, rules }` to the settings user layer. */
|
|
98
|
+
writeRoles(roles: FallbacksRoles): Promise<void>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* In-memory per-apply seed manager (spec §9.2): declare / readback /
|
|
102
|
+
* revert over the operator config through a `SeedsIo` seam. Created in
|
|
103
|
+
* `apply()` (per-apply, no module-level global) with a structured logger;
|
|
104
|
+
* warn messages carry the `llm-fallbacks: seeds:` prefix (spec §9.7).
|
|
105
|
+
*/
|
|
106
|
+
export declare class FallbacksSeedManager {
|
|
107
|
+
private readonly logger;
|
|
108
|
+
private registry;
|
|
109
|
+
constructor(logger: FallbacksConfigLogger);
|
|
110
|
+
/**
|
|
111
|
+
* Declare seeds with replacement semantics — the batch is the
|
|
112
|
+
* companion's FULL current declaration set; ids omitted from the batch
|
|
113
|
+
* drop out of the registry while their rows remain (R2).
|
|
114
|
+
*
|
|
115
|
+
* Per-id validation AS DECLARED (spec §9.3): non-string / pattern miss /
|
|
116
|
+
* reserved `inherit` / duplicate-in-batch → skip + warn; valid siblings
|
|
117
|
+
* still apply (AC-5). Materializes per spec §9.2, writes only when the
|
|
118
|
+
* computed `{ list, rules }` differs from the current composed roles
|
|
119
|
+
* (idempotent, AC-1), and commits the registry only after a successful
|
|
120
|
+
* write (compute → write → commit; retry-safe).
|
|
121
|
+
*/
|
|
122
|
+
declare(seeds: readonly SeedDeclaration[], io: SeedsIo): Promise<SeedDeclareOutcome>;
|
|
123
|
+
/**
|
|
124
|
+
* Readback (b) — sync, derived: every config row annotated with
|
|
125
|
+
* `seeded` / `personaOverridden` / `seedPersona` (trimmed row-id
|
|
126
|
+
* membership in the live declaration set; persona inequality). Nothing
|
|
127
|
+
* override-shaped is stored, so a config round-trip cannot orphan state.
|
|
128
|
+
*/
|
|
129
|
+
effectiveRoles(io: SeedsIo): EffectiveRolesReadback;
|
|
130
|
+
/** Card badge state (spec §9.4): seeded rows, with the override flag. */
|
|
131
|
+
wireStatus(io: SeedsIo): SeedsWireStatus[];
|
|
132
|
+
/**
|
|
133
|
+
* Revert one id to the CURRENT declared seed default (AC-3). Writes
|
|
134
|
+
* persona only — the row is otherwise copied verbatim (R4). Ids absent
|
|
135
|
+
* from the registry (`not-seeded`) or with a deleted row (`row-absent`)
|
|
136
|
+
* return a non-reverted outcome without throwing; a failed settings
|
|
137
|
+
* write propagates loudly (spec §9.1).
|
|
138
|
+
*/
|
|
139
|
+
revert(id: string, io: SeedsIo): Promise<SeedRevertOutcome>;
|
|
140
|
+
private warnSkip;
|
|
141
|
+
}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"dsh",
|
|
6
6
|
"dsh-plugin"
|
|
7
7
|
],
|
|
8
|
-
"version": "0.1.
|
|
8
|
+
"version": "0.1.5",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"release:prepare": "tsx scripts/prepare-release.ts",
|
|
50
50
|
"release:validate": "tsx scripts/validate-release-version.ts",
|
|
51
51
|
"test": "vitest run",
|
|
52
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit && tsc --noEmit",
|
|
52
53
|
"prepare": "pnpm run build"
|
|
53
54
|
},
|
|
54
55
|
"engines": {
|