@myvillage/cli 1.78.0 → 1.80.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 +1 -1
- package/src/agent-runtime/loop.js +13 -0
- package/src/commands/agent-local.js +27 -3
- package/src/utils/api.js +9 -0
package/package.json
CHANGED
|
@@ -15,6 +15,7 @@ import { isWithinActiveHours, getNextCheckInMs } from './scheduler.js';
|
|
|
15
15
|
import { parse as parseYaml } from 'yaml';
|
|
16
16
|
import { postAgentHeartbeat, listAgentTasks, claimAgentTask, completeAgentTask, refreshAccessToken } from '../utils/api.js';
|
|
17
17
|
import { getAccessToken, isTokenExpired } from '../utils/auth.js';
|
|
18
|
+
import { getConfig } from '../utils/config.js';
|
|
18
19
|
import { readAgentWisdom } from '../utils/wisdom.js';
|
|
19
20
|
|
|
20
21
|
export async function agentLoop(agentName, { signal }) {
|
|
@@ -39,6 +40,7 @@ export async function agentLoop(agentName, { signal }) {
|
|
|
39
40
|
anthropic: 'claude-sonnet-4-5-20250929',
|
|
40
41
|
openai: 'gpt-4o',
|
|
41
42
|
'self-hosted': '',
|
|
43
|
+
myvillage: 'vee-1.3',
|
|
42
44
|
};
|
|
43
45
|
const modelId =
|
|
44
46
|
config.brain?.model || defaultModel.model || DEFAULT_MODEL_ID[provider] || DEFAULT_MODEL_ID.anthropic;
|
|
@@ -63,6 +65,17 @@ export async function agentLoop(agentName, { signal }) {
|
|
|
63
65
|
const apiKey = process.env.SELF_HOSTED_API_KEY || globalConfig.selfHostedApiKey || 'not-needed';
|
|
64
66
|
const openai = createOpenAI({ apiKey, baseURL });
|
|
65
67
|
model = openai(modelId);
|
|
68
|
+
} else if (provider === 'myvillage') {
|
|
69
|
+
// MyVillage-hosted models via the AI Gateway. OpenAI-compatible; the villager's
|
|
70
|
+
// OAuth token is the credential, and MVTs are deducted server-side by usage.
|
|
71
|
+
const token = getAccessToken();
|
|
72
|
+
if (!token) {
|
|
73
|
+
logActivity(agentDir, { type: 'error', error: 'Not logged in for MyVillage-hosted model' });
|
|
74
|
+
throw new Error('Not logged in. Run `myvillage login` to use MyVillage-hosted models.');
|
|
75
|
+
}
|
|
76
|
+
const { apiBaseUrl } = getConfig();
|
|
77
|
+
const openai = createOpenAI({ apiKey: token, baseURL: `${apiBaseUrl}/ai` });
|
|
78
|
+
model = openai(modelId);
|
|
66
79
|
} else {
|
|
67
80
|
const apiKey = process.env.ANTHROPIC_API_KEY || globalConfig.anthropicApiKey;
|
|
68
81
|
if (!apiKey) {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
shareKnowledgeAsAgent,
|
|
30
30
|
retryAgentTask,
|
|
31
31
|
retryFailedAgentTasks,
|
|
32
|
+
listHostedModels,
|
|
32
33
|
} from '../utils/api.js';
|
|
33
34
|
import {
|
|
34
35
|
getAgentDir,
|
|
@@ -129,6 +130,7 @@ export async function agentCreateLocalCommand() {
|
|
|
129
130
|
name: 'provider',
|
|
130
131
|
message: 'AI provider:',
|
|
131
132
|
choices: [
|
|
133
|
+
{ name: 'MyVillage (hosted — billed in MVTs)', value: 'myvillage' },
|
|
132
134
|
{ name: 'Anthropic (Claude)', value: 'anthropic' },
|
|
133
135
|
{ name: 'OpenAI (GPT)', value: 'openai' },
|
|
134
136
|
],
|
|
@@ -138,7 +140,23 @@ export async function agentCreateLocalCommand() {
|
|
|
138
140
|
type: 'list',
|
|
139
141
|
name: 'model',
|
|
140
142
|
message: 'Model:',
|
|
141
|
-
choices: (prev) => {
|
|
143
|
+
choices: async (prev) => {
|
|
144
|
+
if (prev.provider === 'myvillage') {
|
|
145
|
+
// Pull the live catalog of hosted models from the gateway; fall back to
|
|
146
|
+
// the default slug if the network/catalog is unavailable.
|
|
147
|
+
try {
|
|
148
|
+
const models = await listHostedModels();
|
|
149
|
+
if (Array.isArray(models) && models.length > 0) {
|
|
150
|
+
return models.map((m) => ({
|
|
151
|
+
name: m.description ? `${m.name} — ${m.description}` : m.name || m.slug,
|
|
152
|
+
value: m.slug,
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
/* offline or gateway unavailable — fall through to default */
|
|
157
|
+
}
|
|
158
|
+
return [{ name: 'Vee 1.3 (recommended)', value: 'vee-1.3' }];
|
|
159
|
+
}
|
|
142
160
|
if (prev.provider === 'openai') {
|
|
143
161
|
return [
|
|
144
162
|
{ name: 'gpt-4o (recommended)', value: 'gpt-4o' },
|
|
@@ -271,7 +289,13 @@ export async function agentStartCommand(name) {
|
|
|
271
289
|
let providerLabel;
|
|
272
290
|
let consoleUrl;
|
|
273
291
|
|
|
274
|
-
if (provider === '
|
|
292
|
+
if (provider === 'myvillage') {
|
|
293
|
+
// MyVillage-hosted models authenticate with the OAuth login, not an API key.
|
|
294
|
+
if (!getAccessToken()) {
|
|
295
|
+
console.log(chalk.yellow('\n Log in to use MyVillage-hosted models: run `myvillage login`.\n'));
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
} else if (provider === 'openai') {
|
|
275
299
|
apiKey = cliConfig.openaiApiKey || process.env.OPENAI_API_KEY;
|
|
276
300
|
configKeyName = 'openaiApiKey';
|
|
277
301
|
providerLabel = 'OpenAI';
|
|
@@ -283,7 +307,7 @@ export async function agentStartCommand(name) {
|
|
|
283
307
|
consoleUrl = 'https://console.anthropic.com';
|
|
284
308
|
}
|
|
285
309
|
|
|
286
|
-
if (!apiKey) {
|
|
310
|
+
if (provider !== 'myvillage' && !apiKey) {
|
|
287
311
|
console.log(chalk.yellow(`\n ${providerLabel} API key required for this agent.`));
|
|
288
312
|
console.log(brand.teal(` Get yours at: ${consoleUrl}\n`));
|
|
289
313
|
|
package/src/utils/api.js
CHANGED
|
@@ -131,6 +131,15 @@ export async function getGameStatus(gameId) {
|
|
|
131
131
|
return response.data;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// ── AI Gateway (MyVillage-hosted models) ────────────────
|
|
135
|
+
|
|
136
|
+
/** List the MyVillage-hosted models available through the AI Gateway. */
|
|
137
|
+
export async function listHostedModels() {
|
|
138
|
+
const client = getApiClient();
|
|
139
|
+
const response = await client.get('/ai/models');
|
|
140
|
+
return response.data?.models || [];
|
|
141
|
+
}
|
|
142
|
+
|
|
134
143
|
// ── Network API Client (/api/network) ───────────────────
|
|
135
144
|
|
|
136
145
|
export function getNetworkClient() {
|