@myvillage/cli 1.71.0 → 1.72.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myvillage/cli",
3
- "version": "1.71.0",
3
+ "version": "1.72.0",
4
4
  "description": "MyVillageOS CLI for community developers",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,6 +3,8 @@
3
3
  // This becomes the user message sent to the LLM.
4
4
 
5
5
  import { getAgentFeed, getAgentMentions, getAgentEvents } from '../utils/api.js';
6
+ import { listDatasets } from '../utils/dataset-workspace.js';
7
+ import { listModels } from '../utils/model-workspace.js';
6
8
 
7
9
  export async function gatherContext(agentConfig, lastCheckIn, recentActions = []) {
8
10
  const parts = [];
@@ -110,6 +112,33 @@ export async function gatherContext(agentConfig, lastCheckIn, recentActions = []
110
112
  }
111
113
  }
112
114
 
115
+ // Local Lab datasets & models, so the agent knows what it can append to /
116
+ // predict with (and the exact slugs to pass to dataset_append / model_predict).
117
+ // Local-only, synchronous file reads; tfjs is NOT loaded by listing models.
118
+ try {
119
+ const datasets = listDatasets();
120
+ if (datasets.length > 0) {
121
+ parts.push('\nLocal datasets you can add to with dataset_append (use the slug as datasetId):');
122
+ for (const d of datasets.slice(0, 25)) {
123
+ parts.push(`- ${d.slug} — ${d.modality}/${d.taskType}, ${d.stats?.rowCount ?? 0} rows`);
124
+ }
125
+ }
126
+ } catch {
127
+ /* no local datasets / store unavailable — skip */
128
+ }
129
+ try {
130
+ const models = listModels();
131
+ if (models.length > 0) {
132
+ parts.push('\nLocal models you can run with model_predict (use the slug as modelId):');
133
+ for (const m of models.slice(0, 25)) {
134
+ const labels = m.labels?.length ? ` → ${m.labels.join('/')}` : '';
135
+ parts.push(`- ${m.slug} — ${m.modality}/${m.taskType}${labels}`);
136
+ }
137
+ }
138
+ } catch {
139
+ /* no local models / store unavailable — skip */
140
+ }
141
+
113
142
  parts.push('\nDecide what actions to take based on your personality and the current context.');
114
143
  parts.push('IMPORTANT: If you already commented on a post, only comment again if someone ELSE has replied since your last comment. Do not leave multiple unanswered comments on the same post.');
115
144
  parts.push('If there is no new activity and no one has responded to your previous comments, do nothing — that is a valid choice.');
@@ -12,10 +12,13 @@
12
12
  import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, rmSync } from 'fs';
13
13
  import { join } from 'path';
14
14
  import { randomUUID } from 'crypto';
15
- import * as tf from '@tensorflow/tfjs';
16
15
  import { getConfigDir } from './config.js';
17
16
  import { slugify } from './dataset-workspace.js';
18
17
 
18
+ // tfjs is loaded lazily (only in save/load) so listing/reading model manifests —
19
+ // e.g. when injecting "available models" into the agent loop's context — never
20
+ // pulls the heavy tfjs runtime into agent startup.
21
+
19
22
  const MODELS_DIR_NAME = 'models';
20
23
  export const MODEL_SCHEMA_VERSION = '1.0.0';
21
24
 
@@ -71,6 +74,7 @@ export async function saveModel(name, { model, record, datasetSlug, datasetVersi
71
74
  const dir = getModelDir(slug);
72
75
  mkdirSync(dir, { recursive: true });
73
76
 
77
+ const tf = await import('@tensorflow/tfjs');
74
78
  let modelTopology, weightSpecs, weightB64;
75
79
  await model.save(
76
80
  tf.io.withSaveHandler(async (artifacts) => {
@@ -104,6 +108,7 @@ export async function saveModel(name, { model, record, datasetSlug, datasetVersi
104
108
 
105
109
  /** Load a saved tf model back into memory (for predict). */
106
110
  export async function loadModel(slug) {
111
+ const tf = await import('@tensorflow/tfjs');
107
112
  const dir = getModelDir(slug);
108
113
  if (!existsSync(join(dir, 'model.json'))) throw new Error(`Model "${slug}" not found.`);
109
114
  const { modelTopology, weightSpecs } = JSON.parse(readFileSync(join(dir, 'model.json'), 'utf-8'));