myuru 0.2.0 → 0.3.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/bin/myuru.js CHANGED
@@ -49,6 +49,7 @@ program
49
49
  .description('Start a council session — agents deliberate, then execute')
50
50
  .option('--topic <text>', 'Topic for council discussion')
51
51
  .option('--agents <names>', 'Comma-separated agent roles', 'Architect,Reviewer,Tester')
52
+ .option('--model <name>', 'Model for council agents', 'sonnet')
52
53
  .option('--rounds <n>', 'Max deliberation rounds', '3')
53
54
  .option('--execute', 'Auto-execute tasks after deliberation')
54
55
  .action(async (opts) => {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "myuru",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Multi-provider AI agent orchestrator. Coordinate Claude, GPT, and Gemini agents to build software in parallel.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
- "myuru": "./bin/myuru.js"
7
+ "myuru": "bin/myuru.js"
8
8
  },
9
9
  "scripts": {
10
10
  "test": "node --test src/**/*.test.js",
@@ -26,7 +26,7 @@
26
26
  "license": "MIT",
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "https://github.com/Wittlesus/myuru"
29
+ "url": "git+https://github.com/Wittlesus/myuru.git"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=18.0.0"
@@ -2,7 +2,6 @@ const { spawn } = require("child_process");
2
2
  const path = require("path");
3
3
  const http = require("http");
4
4
  const CouncilServer = require("../lib/council-server");
5
- const { TierManager } = require("../lib/tiers");
6
5
 
7
6
  async function council(opts) {
8
7
  const topic = opts.topic;
@@ -14,15 +13,7 @@ async function council(opts) {
14
13
  const agentNames = (opts.agents || "Architect,Reviewer,Tester").split(",").map(a => a.trim());
15
14
  const maxRounds = parseInt(opts.rounds) || 3;
16
15
  const shouldExecute = opts.execute || false;
17
-
18
- // Tier check
19
- const tier = new TierManager("FREE");
20
- try {
21
- tier.enforceLimit(agentNames.length);
22
- } catch (err) {
23
- console.error(err.message);
24
- process.exit(1);
25
- }
16
+ const model = opts.model || "sonnet";
26
17
 
27
18
  console.log("MyUru Council");
28
19
  console.log("─".repeat(50));
@@ -79,7 +70,7 @@ async function council(opts) {
79
70
  delete env.CLAUDECODE;
80
71
 
81
72
  // Intentional spawn — core product functionality
82
- const child = spawn("claude", ["--model", "haiku", "-p"], {
73
+ const child = spawn("claude", ["--model", model, "-p"], {
83
74
  stdio: ["pipe", "pipe", "pipe"],
84
75
  env,
85
76
  shell: true,
@@ -136,7 +127,7 @@ async function council(opts) {
136
127
  delete env.CLAUDECODE;
137
128
 
138
129
  const taskOutput = await new Promise(resolve => {
139
- const child = spawn("claude", ["--model", "haiku", "-p"], {
130
+ const child = spawn("claude", ["--model", model, "-p"], {
140
131
  stdio: ["pipe", "pipe", "pipe"], env, shell: true,
141
132
  });
142
133
  child.stdin.write(extractPrompt);
@@ -27,7 +27,7 @@ async function run(opts) {
27
27
  const concurrent = opts.concurrent || config.concurrent || false;
28
28
 
29
29
  const execMode = concurrent ? "concurrent" : "sequential";
30
- console.log(`MyUru v0.1.0 | ${providerName}/${model}`);
30
+ console.log(`MyUru v0.3.0 | ${providerName}/${model}`);
31
31
  console.log(`Agents: ${agentCount} | Execution: ${execMode}`);
32
32
  console.log("─".repeat(50));
33
33
 
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Gemini provider — uses the Google Generative AI API via fetch.
3
+ * Requires GEMINI_API_KEY in environment.
4
+ */
5
+ class GeminiProvider {
6
+ constructor(opts = {}) {
7
+ this.apiKey = opts.apiKey || process.env.GEMINI_API_KEY;
8
+ this.baseUrl = opts.baseUrl || "https://generativelanguage.googleapis.com/v1beta";
9
+ }
10
+
11
+ static MODELS = {
12
+ "gemini-2.0-flash": "gemini-2.0-flash",
13
+ "gemini-2.0-pro": "gemini-2.0-pro",
14
+ "gemini-1.5-flash": "gemini-1.5-flash",
15
+ "gemini-1.5-pro": "gemini-1.5-pro",
16
+ };
17
+
18
+ async invoke(prompt, { model = "gemini-2.0-flash", systemPrompt = "" } = {}) {
19
+ if (!this.apiKey) {
20
+ throw new Error("GEMINI_API_KEY not set. Run: export GEMINI_API_KEY=...");
21
+ }
22
+
23
+ const modelId = GeminiProvider.MODELS[model] || model;
24
+ const url = `${this.baseUrl}/models/${modelId}:generateContent?key=${this.apiKey}`;
25
+
26
+ const contents = [];
27
+ if (systemPrompt) {
28
+ contents.push({ role: "user", parts: [{ text: systemPrompt }] });
29
+ contents.push({ role: "model", parts: [{ text: "Understood." }] });
30
+ }
31
+ contents.push({ role: "user", parts: [{ text: prompt }] });
32
+
33
+ const res = await fetch(url, {
34
+ method: "POST",
35
+ headers: { "Content-Type": "application/json" },
36
+ body: JSON.stringify({
37
+ contents,
38
+ generationConfig: { maxOutputTokens: 8192 },
39
+ }),
40
+ });
41
+
42
+ if (!res.ok) {
43
+ const text = await res.text();
44
+ throw new Error(`Gemini API error ${res.status}: ${text.slice(0, 200)}`);
45
+ }
46
+
47
+ const data = await res.json();
48
+ return data.candidates?.[0]?.content?.parts?.[0]?.text || "";
49
+ }
50
+
51
+ buildCommand() {
52
+ throw new Error("Gemini provider uses invoke() directly, not buildCommand().");
53
+ }
54
+ }
55
+
56
+ module.exports = GeminiProvider;
@@ -1,9 +1,11 @@
1
1
  const ClaudeProvider = require("./claude");
2
2
  const OpenAIProvider = require("./openai");
3
+ const GeminiProvider = require("./gemini");
3
4
 
4
5
  const PROVIDERS = {
5
6
  claude: ClaudeProvider,
6
7
  openai: OpenAIProvider,
8
+ gemini: GeminiProvider,
7
9
  };
8
10
 
9
11
  function createProvider(name, opts = {}) {
@@ -14,4 +16,4 @@ function createProvider(name, opts = {}) {
14
16
  return new Provider(opts);
15
17
  }
16
18
 
17
- module.exports = { createProvider, ClaudeProvider, OpenAIProvider, PROVIDERS };
19
+ module.exports = { createProvider, ClaudeProvider, OpenAIProvider, GeminiProvider, PROVIDERS };