@mailwoman/neural-weights-fr-fr 7.4.0 → 7.6.0
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/package.json +2 -2
- package/scripts/link-dev-weights.ts +75 -62
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailwoman/neural-weights-fr-fr",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.0",
|
|
4
4
|
"description": "Mailwoman neural-classifier weights for locale 'fr-fr'. Data-only overlay — shares the base model.onnx + tokenizer.model from @mailwoman/neural-weights-en-us (they are byte-identical); ships only the fr-specific data siblings. Loaded by @mailwoman/neural at runtime.",
|
|
5
5
|
"license": "AGPL-3.0-only OR LicenseRef-Commercial",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@mailwoman/neural-weights-en-us": "7.
|
|
30
|
+
"@mailwoman/neural-weights-en-us": "7.6.0"
|
|
31
31
|
},
|
|
32
32
|
"mailwoman": {
|
|
33
33
|
"baseWeights": "@mailwoman/neural-weights-en-us"
|
|
@@ -4,42 +4,37 @@
|
|
|
4
4
|
* @license AGPL-3.0
|
|
5
5
|
* @author Teffen Ellis, et al.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Materialize the fr-fr overlay's dev artifacts. See
|
|
8
|
+
* @mailwoman/neural-weights-en-us/scripts/link-dev-weights.ts for the base rationale.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
10
|
+
* #1179 OVERLAY FORM (2026-07-23 rewrite): fr-fr declares `mailwoman.baseWeights:
|
|
11
|
+
* "@mailwoman/neural-weights-en-us"`, so `resolveWeights` falls through to the en-us package
|
|
12
|
+
* for `model.onnx` / `tokenizer.model` / the card. This script therefore no longer links a
|
|
13
|
+
* model or tokenizer at all — it REMOVES any leftover local pair so the base fallback engages.
|
|
14
|
+
* (The previous version re-symlinked a pinned v241-fr-nsplice model on every `yarn test`;
|
|
15
|
+
* since #1179 that local file SHADOWED the base fallback, silently running the stale model for
|
|
16
|
+
* every dev fr-fr parse, and its #397 md5 guard could never pass against the en-us card. One
|
|
17
|
+
* model, one pin — en-us's script owns it.)
|
|
18
|
+
*
|
|
19
|
+
* What fr-fr DOES own locally (locale-specific soft-feed siblings; `resolveFromPackageDir`
|
|
20
|
+
* resolves these from the overlay dir with no base fallback):
|
|
21
|
+
*
|
|
22
|
+
* - `anchor-lexicon-v1.json` / `country-surface-lexicon-v1.json` — checked-in repo files,
|
|
23
|
+
* symlinked from `data/gazetteer/`.
|
|
24
|
+
* - `postcode-fr.bin` — derived from the WOF intl postcode shard
|
|
25
|
+
* (`softFeed.postcodeDBByCountry.fr` = postalcode-intl.db), built in place via the compiled
|
|
26
|
+
* `gazetteer postcode-binary` CLI (skip-if-exists; rebuilds in seconds). Without it a fresh
|
|
27
|
+
* worktree parses anchor-OFF — see the en-us script's section comment for the CI failure
|
|
28
|
+
* this caused.
|
|
16
29
|
*/
|
|
17
30
|
|
|
18
|
-
import {
|
|
19
|
-
import { existsSync,
|
|
31
|
+
import { spawnSync } from "node:child_process"
|
|
32
|
+
import { existsSync, lstatSync, symlinkSync, unlinkSync } from "node:fs"
|
|
20
33
|
import { resolve } from "node:path"
|
|
21
34
|
|
|
22
|
-
import { $public } from "@mailwoman/core/env"
|
|
23
35
|
import { dataRootPath, repoRootPath } from "@mailwoman/core/utils"
|
|
24
36
|
|
|
25
37
|
const PKG_DIR = repoRootPath("neural-weights-fr-fr")
|
|
26
|
-
// In lockstep with en-us's DEFAULT_* (one multilingual artifact serves both) — v5.9.0
|
|
27
|
-
// v241-fr-nsplice-ft pair. The 2026-07-02 ship missed this bump (both linkers still pinned
|
|
28
|
-
// the demo-only v4.16.0 pair); the guard below now fails loud on any future miss.
|
|
29
|
-
const SRC_MODEL =
|
|
30
|
-
$public.MAILWOMAN_DEV_MODEL || dataRootPath("models", "quantized", "model-v241-fr-nsplice-ft-step-12000-int8.onnx")
|
|
31
|
-
const SRC_TOKENIZER =
|
|
32
|
-
$public.MAILWOMAN_DEV_TOKENIZER || dataRootPath("models", "tokenizer", "v0.8.0-fr-nsplice", "tokenizer.model")
|
|
33
|
-
|
|
34
|
-
if (!existsSync(SRC_MODEL)) {
|
|
35
|
-
console.error(`missing source model: ${SRC_MODEL}`)
|
|
36
|
-
process.exit(1)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!existsSync(SRC_TOKENIZER)) {
|
|
40
|
-
console.error(`missing source tokenizer: ${SRC_TOKENIZER}`)
|
|
41
|
-
process.exit(1)
|
|
42
|
-
}
|
|
43
38
|
|
|
44
39
|
/** Replicate `ln -sf SRC DEST`: drop any pre-existing link/file at the destination, then symlink. */
|
|
45
40
|
function linkForce(src: string, dest: string): void {
|
|
@@ -50,44 +45,62 @@ function linkForce(src: string, dest: string): void {
|
|
|
50
45
|
symlinkSync(src, dest)
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
/** Remove a leftover local file/symlink so the #1179 base-weights fallback engages. */
|
|
49
|
+
function removeIfPresent(dest: string): void {
|
|
50
|
+
try {
|
|
51
|
+
lstatSync(dest)
|
|
52
|
+
} catch {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
unlinkSync(dest)
|
|
56
|
+
console.log(`removed stale local ${dest} (base fallback to en-us engages)`)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
removeIfPresent(resolve(PKG_DIR, "model.onnx"))
|
|
60
|
+
removeIfPresent(resolve(PKG_DIR, "tokenizer.model"))
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
// --- soft-feed siblings (locale-owned; the fresh-worktree anchor-OFF gap) ----------------
|
|
63
|
+
const SRC_GAZETTEER_LEXICON = repoRootPath("data", "gazetteer", "anchor-lexicon-v1.json")
|
|
64
|
+
const SRC_COUNTRY_LEXICON = repoRootPath("data", "gazetteer", "country-surface-lexicon-v1.json")
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
if (existsSync(SRC_GAZETTEER_LEXICON)) {
|
|
67
|
+
linkForce(SRC_GAZETTEER_LEXICON, resolve(PKG_DIR, "anchor-lexicon-v1.json"))
|
|
68
|
+
console.log(`linked ${PKG_DIR}/anchor-lexicon-v1.json`)
|
|
69
|
+
} else {
|
|
70
|
+
console.error(`WARNING: missing ${SRC_GAZETTEER_LEXICON} — gazetteer channel will resolve OFF in this worktree.`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (existsSync(SRC_COUNTRY_LEXICON)) {
|
|
74
|
+
linkForce(SRC_COUNTRY_LEXICON, resolve(PKG_DIR, "country-surface-lexicon-v1.json"))
|
|
75
|
+
console.log(`linked ${PKG_DIR}/country-surface-lexicon-v1.json`)
|
|
76
|
+
} else {
|
|
77
|
+
console.error(`WARNING: missing ${SRC_COUNTRY_LEXICON} — country channel will resolve OFF in this worktree.`)
|
|
78
|
+
}
|
|
69
79
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
($public.MAILWOMAN_DEV_TOKENIZER && label === "tokenizer")
|
|
74
|
-
)
|
|
75
|
-
continue
|
|
80
|
+
const FR_WOF_DB = dataRootPath("wof", "postalcode-intl.db")
|
|
81
|
+
const CLI = repoRootPath("mailwoman", "out", "cli.js")
|
|
82
|
+
const POSTCODE_BIN_DEST = resolve(PKG_DIR, "postcode-fr.bin")
|
|
76
83
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
if (existsSync(POSTCODE_BIN_DEST)) {
|
|
85
|
+
console.log(`skipped postcode-fr.bin build — ${POSTCODE_BIN_DEST} already present`)
|
|
86
|
+
} else if (!existsSync(CLI)) {
|
|
87
|
+
console.error(
|
|
88
|
+
`WARNING: ${CLI} not built — run \`yarn compile\` first, then re-run this script to build postcode-fr.bin.`
|
|
89
|
+
)
|
|
90
|
+
} else if (!existsSync(FR_WOF_DB)) {
|
|
91
|
+
console.error(
|
|
92
|
+
`WARNING: missing ${FR_WOF_DB} — postcode-fr.bin not built; the anchor channel will resolve OFF for FR.`
|
|
93
|
+
)
|
|
94
|
+
} else {
|
|
95
|
+
const result = spawnSync(
|
|
96
|
+
process.execPath,
|
|
97
|
+
[CLI, "gazetteer", "postcode-binary", "--out", PKG_DIR, "--locale", `FR:${FR_WOF_DB}`],
|
|
98
|
+
{ stdio: "inherit" }
|
|
99
|
+
)
|
|
84
100
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
)
|
|
89
|
-
console.error(" Bump this script's SRC_* defaults in lockstep with en-us on each ship.")
|
|
90
|
-
process.exit(1)
|
|
91
|
-
}
|
|
101
|
+
if (result.status !== 0 || !existsSync(POSTCODE_BIN_DEST)) {
|
|
102
|
+
console.error(`ERROR: failed to build ${POSTCODE_BIN_DEST} (exit ${result.status})`)
|
|
103
|
+
process.exit(1)
|
|
92
104
|
}
|
|
105
|
+
console.log(`built ${POSTCODE_BIN_DEST}`)
|
|
93
106
|
}
|