careerclaw-js 1.11.0 → 1.11.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.11.1](https://github.com/orestes-garcia-martinez/careerclaw-js/compare/careerclaw-js-v1.11.0...careerclaw-js-v1.11.1) (2026-04-08)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **embedding:** chunk ONNX inference to prevent OOM on large job lists ([#84](https://github.com/orestes-garcia-martinez/careerclaw-js/issues/84)) ([f6f1b15](https://github.com/orestes-garcia-martinez/careerclaw-js/commit/f6f1b15f4ca5a5217382b20f76f03c539abd02ac))
9
+
10
+ ## [1.11.1] (2026-04-08)
11
+
12
+ ### Bug Fixes
13
+
14
+ - **embedding:** chunk ONNX inference into batches of 8 to prevent OOM on constrained instances — a single forward pass over 50+ jobs caused activation tensors to exceed available memory on 2 GB hosts; sequential 8-text chunks cap per-pass memory to ~18 MB regardless of job count
15
+
3
16
  ## [1.11.0](https://github.com/orestes-garcia-martinez/careerclaw-js/compare/careerclaw-js-v1.10.1...careerclaw-js-v1.11.0) (2026-04-08)
4
17
 
5
18
 
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: CareerClaw
3
- version: 1.11.0
3
+ version: 1.11.1
4
4
  description: >
5
5
  Run a job search briefing, find job matches, draft outreach emails,
6
6
  or track job applications. Triggers on: daily briefing, job search,
package/dist/config.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare const HTTP_TIMEOUT_MS = 15000;
19
19
  * User-Agent sent with all outbound requests.
20
20
  * Identifies the tool and provides a contact point per robots.txt convention.
21
21
  */
22
- export declare const USER_AGENT = "careerclaw-js/1.11.0 (https://github.com/orestes-garcia-martinez/careerclaw-js)";
22
+ export declare const USER_AGENT = "careerclaw-js/1.11.1 (https://github.com/orestes-garcia-martinez/careerclaw-js)";
23
23
  /** RemoteOK RSS feed — public, no auth required. */
24
24
  export declare const REMOTEOK_RSS_URL = "https://remoteok.com/remote-jobs.rss";
25
25
  /**
package/dist/config.js CHANGED
@@ -34,7 +34,7 @@ export const HTTP_TIMEOUT_MS = 15_000;
34
34
  * User-Agent sent with all outbound requests.
35
35
  * Identifies the tool and provides a contact point per robots.txt convention.
36
36
  */
37
- export const USER_AGENT = "careerclaw-js/1.11.0 (https://github.com/orestes-garcia-martinez/careerclaw-js)";
37
+ export const USER_AGENT = "careerclaw-js/1.11.1 (https://github.com/orestes-garcia-martinez/careerclaw-js)";
38
38
  // ---------------------------------------------------------------------------
39
39
  // Job sources
40
40
  // ---------------------------------------------------------------------------
@@ -25,6 +25,7 @@ export declare class LocalEmbeddingProvider implements EmbeddingProvider {
25
25
  dimensions: number;
26
26
  readonly modelName: string;
27
27
  private pipe;
28
+ private static readonly BATCH_SIZE;
28
29
  constructor(modelName?: string);
29
30
  /**
30
31
  * Load the model from `modelDir` and detect its output dimensionality.
@@ -40,10 +41,16 @@ export declare class LocalEmbeddingProvider implements EmbeddingProvider {
40
41
  */
41
42
  initialize(modelDir: string): Promise<void>;
42
43
  /**
43
- * Embed a batch of texts in a single ONNX forward pass.
44
- * Returns one L2-normalized Float32Array per input text.
45
- * Tensor stride is read from `output.dims[1]` on every call
46
- * consistent with the dimensions derived during initialize().
44
+ * Embed a list of texts and return one L2-normalized Float32Array per input.
45
+ *
46
+ * Inputs are processed in sequential chunks of BATCH_SIZE to keep ONNX
47
+ * activation tensors small. A single pass over all N texts would produce
48
+ * a tensor of shape [N, seqLen, hiddenDim] that can OOM on constrained
49
+ * instances (e.g. 2 GB Lightsail) when N is large. Chunking caps the
50
+ * per-pass memory budget regardless of how many jobs are in the briefing.
51
+ *
52
+ * Tensor stride is read from output.dims[1] on every chunk — consistent
53
+ * with the dimensions derived during initialize().
47
54
  */
48
55
  embed(texts: string[]): Promise<Float32Array[]>;
49
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"local-provider.d.ts","sourceRoot":"","sources":["../../src/embedding/local-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOvD,qBAAa,sBAAuB,YAAW,iBAAiB;IAG9D,UAAU,EAAE,MAAM,CAAK;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,IAAI,CAAyB;gBAEzB,SAAS,GAAE,MAAkC;IAIzD;;;;;;;;;;;OAWG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjD;;;;;OAKG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAqBtD"}
1
+ {"version":3,"file":"local-provider.d.ts","sourceRoot":"","sources":["../../src/embedding/local-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOvD,qBAAa,sBAAuB,YAAW,iBAAiB;IAG9D,UAAU,EAAE,MAAM,CAAK;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,IAAI,CAAyB;IAKrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;gBAE3B,SAAS,GAAE,MAAkC;IAIzD;;;;;;;;;;;OAWG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjD;;;;;;;;;;;OAWG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAwBtD"}
@@ -26,6 +26,10 @@ export class LocalEmbeddingProvider {
26
26
  dimensions = 0;
27
27
  modelName;
28
28
  pipe = null;
29
+ // Maximum number of texts per ONNX forward pass. Keeping batches small
30
+ // bounds the activation tensor size during inference (~18 MB at 8 texts ×
31
+ // 256 tokens × 384 dims) and prevents OOM on constrained instances.
32
+ static BATCH_SIZE = 8;
29
33
  constructor(modelName = "Xenova/all-MiniLM-L6-v2") {
30
34
  this.modelName = modelName;
31
35
  }
@@ -56,10 +60,16 @@ export class LocalEmbeddingProvider {
56
60
  this.dimensions = probe.dims[1];
57
61
  }
58
62
  /**
59
- * Embed a batch of texts in a single ONNX forward pass.
60
- * Returns one L2-normalized Float32Array per input text.
61
- * Tensor stride is read from `output.dims[1]` on every call
62
- * consistent with the dimensions derived during initialize().
63
+ * Embed a list of texts and return one L2-normalized Float32Array per input.
64
+ *
65
+ * Inputs are processed in sequential chunks of BATCH_SIZE to keep ONNX
66
+ * activation tensors small. A single pass over all N texts would produce
67
+ * a tensor of shape [N, seqLen, hiddenDim] that can OOM on constrained
68
+ * instances (e.g. 2 GB Lightsail) when N is large. Chunking caps the
69
+ * per-pass memory budget regardless of how many jobs are in the briefing.
70
+ *
71
+ * Tensor stride is read from output.dims[1] on every chunk — consistent
72
+ * with the dimensions derived during initialize().
63
73
  */
64
74
  async embed(texts) {
65
75
  if (!this.pipe) {
@@ -68,14 +78,15 @@ export class LocalEmbeddingProvider {
68
78
  }
69
79
  if (texts.length === 0)
70
80
  return [];
71
- const output = await this.pipe(texts, { pooling: "mean", normalize: true });
72
- // Use output.dims[1] as the authoritative stride for this call.
73
- // This matches this.dimensions (set during initialize) and is safe
74
- // even if called with a single-text batch where dims may be [1, N].
75
- const dims = output.dims[1];
76
81
  const vectors = [];
77
- for (let i = 0; i < texts.length; i++) {
78
- vectors.push(output.data.slice(i * dims, (i + 1) * dims));
82
+ for (let i = 0; i < texts.length; i += LocalEmbeddingProvider.BATCH_SIZE) {
83
+ const chunk = texts.slice(i, i + LocalEmbeddingProvider.BATCH_SIZE);
84
+ const output = await this.pipe(chunk, { pooling: "mean", normalize: true });
85
+ // Use output.dims[1] as the authoritative stride for this chunk.
86
+ const dims = output.dims[1];
87
+ for (let j = 0; j < chunk.length; j++) {
88
+ vectors.push(output.data.slice(j * dims, (j + 1) * dims));
89
+ }
79
90
  }
80
91
  return vectors;
81
92
  }
@@ -1 +1 @@
1
- {"version":3,"file":"local-provider.js","sourceRoot":"","sources":["../../src/embedding/local-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,MAAM,OAAO,sBAAsB;IACjC,sDAAsD;IACtD,wEAAwE;IACxE,UAAU,GAAW,CAAC,CAAC;IACd,SAAS,CAAS;IAEnB,IAAI,GAAoB,IAAI,CAAC;IAErC,YAAY,YAAoB,yBAAyB;QACvD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,UAAU,CAAC,QAAgB;QAC/B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAE/D,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxB,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,4BAA4B;QAC3D,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE5B,IAAI,CAAC,IAAI,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE;YAC/D,SAAS,EAAE,IAAI,EAAE,+CAA+C;SACjE,CAAa,CAAC;QAEf,yEAAyE;QACzE,qEAAqE;QACrE,8DAA8D;QAC9D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC;IAC5C,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,KAAe;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC7D,iDAAiD,CAClD,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5E,gEAAgE;QAChE,mEAAmE;QACnE,oEAAoE;QACpE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC;QACtC,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAiB,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"local-provider.js","sourceRoot":"","sources":["../../src/embedding/local-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,MAAM,OAAO,sBAAsB;IACjC,sDAAsD;IACtD,wEAAwE;IACxE,UAAU,GAAW,CAAC,CAAC;IACd,SAAS,CAAS;IAEnB,IAAI,GAAoB,IAAI,CAAC;IAErC,uEAAuE;IACvE,0EAA0E;IAC1E,oEAAoE;IAC5D,MAAM,CAAU,UAAU,GAAG,CAAC,CAAC;IAEvC,YAAY,YAAoB,yBAAyB;QACvD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,UAAU,CAAC,QAAgB;QAC/B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAE/D,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxB,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC,4BAA4B;QAC3D,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE5B,IAAI,CAAC,IAAI,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE;YAC/D,SAAS,EAAE,IAAI,EAAE,+CAA+C;SACjE,CAAa,CAAC;QAEf,yEAAyE;QACzE,qEAAqE;QACrE,8DAA8D;QAC9D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC;IAC5C,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,KAAK,CAAC,KAAe;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC7D,iDAAiD,CAClD,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,sBAAsB,CAAC,UAAU,EAAE,CAAC;YACzE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5E,iEAAiE;YACjE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAiB,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "careerclaw-js",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
4
4
  "description": "AI-powered job search automation for ClawOS, with a standalone Node.js runtime for local/manual workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",