omniharness-cli 0.1.17 → 0.1.19
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/README.md +2 -4
- package/cli.cjs +9 -0
- package/dist/agent/mastraEngine.d.ts +19 -0
- package/dist/agent/mastraEngine.js +82 -0
- package/dist/agent/mastraEngine.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/omniRoute.d.ts +52 -0
- package/dist/config/omniRoute.js +138 -0
- package/dist/config/omniRoute.js.map +1 -0
- package/dist/tools/systemTools.d.ts +27 -0
- package/dist/tools/systemTools.js +79 -0
- package/dist/tools/systemTools.js.map +1 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/terminalInterface.d.ts +7 -0
- package/dist/ui/terminalInterface.js +59 -0
- package/dist/ui/terminalInterface.js.map +1 -0
- package/package.json +5 -4
- package/cli.js +0 -29
- package/vendor/win32-x64/omniharness.exe +0 -0
package/README.md
CHANGED
|
@@ -6,8 +6,7 @@ models, drives capability-based agents, verifies results, repairs failures, and
|
|
|
6
6
|
learns from past outcomes — while OmniRoute stays responsible for routing model
|
|
7
7
|
requests to providers.
|
|
8
8
|
|
|
9
|
-
This package
|
|
10
|
-
the `omniharness` command is installed by npm and forwards to the bundled binary.
|
|
9
|
+
This package installs the TypeScript/Ink OmniHarness terminal UI; the `omniharness` command launches the bundled CLI.
|
|
11
10
|
|
|
12
11
|
## Install
|
|
13
12
|
|
|
@@ -44,8 +43,7 @@ config, sessions, logs, or telemetry. The key is redacted from all output;
|
|
|
44
43
|
|
|
45
44
|
## Notes
|
|
46
45
|
|
|
47
|
-
-
|
|
48
|
-
building the Go binary and publishing a new release.
|
|
46
|
+
- Node.js 20 or newer is required to run the CLI.
|
|
49
47
|
- Publishing is automatic: every push to `main` on GitHub runs
|
|
50
48
|
`.github/workflows/publish.yml`, which bumps the version, verifies
|
|
51
49
|
(vet + tests), builds, and publishes via **npm trusted publishing (OIDC)**
|
package/cli.cjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
import(path.join(__dirname, 'dist', 'cli.js')).catch((error) => {
|
|
7
|
+
console.error(`omniharness-cli: failed to launch: ${error instanceof Error ? error.message : String(error)}`);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Agent } from '@mastra/core/agent';
|
|
2
|
+
import { OmniRouteClient } from '../config/omniRoute.js';
|
|
3
|
+
import type { HarnessState } from '../types/index.js';
|
|
4
|
+
import { type SystemTools } from '../tools/systemTools.js';
|
|
5
|
+
export interface MastraEngineConfig {
|
|
6
|
+
workspaceRoot: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
endpoint?: string;
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
shellAllowed?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface MastraEngine {
|
|
13
|
+
readonly agent: Agent;
|
|
14
|
+
readonly client: OmniRouteClient;
|
|
15
|
+
readonly tools: SystemTools;
|
|
16
|
+
readonly state: HarnessState;
|
|
17
|
+
run(prompt: string, signal?: AbortSignal): Promise<string>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createMastraEngine(config: MastraEngineConfig): MastraEngine;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Agent } from '@mastra/core/agent';
|
|
2
|
+
import { createTool } from '@mastra/core/tools';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { OmniRouteClient } from '../config/omniRoute.js';
|
|
5
|
+
import { createSystemTools } from '../tools/systemTools.js';
|
|
6
|
+
function mastraTool(tool, inputSchema, outputSchema) {
|
|
7
|
+
return createTool({
|
|
8
|
+
id: tool.name,
|
|
9
|
+
description: tool.description,
|
|
10
|
+
inputSchema,
|
|
11
|
+
outputSchema,
|
|
12
|
+
execute: (input) => tool.execute(input),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function omniRouteModel(client, model) {
|
|
16
|
+
return {
|
|
17
|
+
specificationVersion: 'v1',
|
|
18
|
+
provider: 'omniroute',
|
|
19
|
+
modelId: model,
|
|
20
|
+
defaultObjectGenerationMode: 'json',
|
|
21
|
+
doGenerate: async (options) => {
|
|
22
|
+
const messages = [];
|
|
23
|
+
for (const part of options.prompt) {
|
|
24
|
+
if (part.role === 'system')
|
|
25
|
+
messages.push({ role: 'system', content: part.content });
|
|
26
|
+
else if (part.role === 'user' || part.role === 'assistant') {
|
|
27
|
+
const content = typeof part.content === 'string' ? part.content : part.content.map((item) => item.type === 'text' ? item.text : '').join('');
|
|
28
|
+
messages.push({ role: part.role, content });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const result = await client.chat(model, messages, options.abortSignal);
|
|
32
|
+
return {
|
|
33
|
+
text: result.content,
|
|
34
|
+
finishReason: 'stop',
|
|
35
|
+
usage: {
|
|
36
|
+
promptTokens: result.usage?.inputTokens ?? 0,
|
|
37
|
+
completionTokens: result.usage?.outputTokens ?? 0,
|
|
38
|
+
},
|
|
39
|
+
rawCall: { rawPrompt: JSON.stringify(options.prompt), rawSettings: {} },
|
|
40
|
+
rawResponse: { headers: Object.fromEntries(result.headers.entries()) },
|
|
41
|
+
warnings: [],
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
doStream: async () => { throw new Error('streaming is not enabled by this adapter'); },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function createMastraEngine(config) {
|
|
48
|
+
const client = new OmniRouteClient({ endpoint: config.endpoint, apiKey: config.apiKey });
|
|
49
|
+
const tools = createSystemTools(config.workspaceRoot, config.shellAllowed ?? false);
|
|
50
|
+
const activeModel = config.model ?? 'auto/best-coding';
|
|
51
|
+
const agent = new Agent({
|
|
52
|
+
name: 'omniharness-developer',
|
|
53
|
+
instructions: 'You are a careful autonomous developer. Inspect context before editing. Explain actions briefly, use tools only inside the workspace, and never claim verification without running it.',
|
|
54
|
+
model: omniRouteModel(client, activeModel),
|
|
55
|
+
tools: {
|
|
56
|
+
read_file: mastraTool(tools.readFile, z.object({ path: z.string().min(1) }), z.object({ path: z.string(), content: z.string() })),
|
|
57
|
+
write_file: mastraTool(tools.writeFile, z.object({ path: z.string().min(1), content: z.string() }), z.object({ path: z.string(), bytes: z.number() })),
|
|
58
|
+
run_command: mastraTool(tools.runCommand, z.object({ command: z.string().min(1), args: z.array(z.string()).optional() }), z.object({ stdout: z.string(), stderr: z.string(), code: z.number() })),
|
|
59
|
+
index_workspace: mastraTool(tools.indexWorkspace, z.void(), z.object({ root: z.string(), indexedAt: z.string().nullable(), files: z.array(z.unknown()).readonly(), contextLocked: z.boolean() })),
|
|
60
|
+
git_diff: mastraTool(tools.gitDiff, z.void(), z.string()),
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const state = {
|
|
64
|
+
taskStatus: 'idle', prompt: '', activeModel,
|
|
65
|
+
workspace: { root: config.workspaceRoot, indexedAt: null, files: [], contextLocked: false },
|
|
66
|
+
metrics: client.snapshotMetrics(), messages: [],
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
agent, client, tools, state,
|
|
70
|
+
async run(prompt, signal) {
|
|
71
|
+
state.prompt = prompt;
|
|
72
|
+
state.taskStatus = 'running';
|
|
73
|
+
const messages = [...state.messages, { role: 'user', content: prompt, createdAt: new Date().toISOString() }];
|
|
74
|
+
const result = await client.chat(state.activeModel, messages.map(({ role, content }) => ({ role: role === 'user' ? 'user' : 'assistant', content })), signal);
|
|
75
|
+
state.taskStatus = 'completed';
|
|
76
|
+
state.metrics = client.snapshotMetrics();
|
|
77
|
+
state.messages = [...messages, { role: 'assistant', content: result.content, createdAt: new Date().toISOString() }];
|
|
78
|
+
return result.content;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=mastraEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastraEngine.js","sourceRoot":"","sources":["../../src/agent/mastraEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import { createMastraEngine } from './agent/mastraEngine.js';
|
|
5
|
+
import { TerminalInterface } from './ui/terminalInterface.js';
|
|
6
|
+
const engine = createMastraEngine({ workspaceRoot: process.cwd() });
|
|
7
|
+
render(_jsx(TerminalInterface, { engine: engine }));
|
|
8
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";;AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AACpE,MAAM,CAAC,KAAC,iBAAiB,IAAC,MAAM,EAAE,MAAM,GAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { OmniRouteMetrics } from '../types/index.js';
|
|
2
|
+
export interface OmniRouteConfig {
|
|
3
|
+
endpoint?: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface OmniRouteCombo {
|
|
8
|
+
name: string;
|
|
9
|
+
strategy?: string;
|
|
10
|
+
models: readonly {
|
|
11
|
+
model?: string;
|
|
12
|
+
providerId?: string;
|
|
13
|
+
kind?: string;
|
|
14
|
+
}[];
|
|
15
|
+
isDefault?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ChatMessage {
|
|
18
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ChatResult {
|
|
22
|
+
content: string;
|
|
23
|
+
model: string;
|
|
24
|
+
usage?: {
|
|
25
|
+
inputTokens: number;
|
|
26
|
+
outputTokens: number;
|
|
27
|
+
totalTokens: number;
|
|
28
|
+
};
|
|
29
|
+
headers: Headers;
|
|
30
|
+
}
|
|
31
|
+
export declare class OmniRouteError extends Error {
|
|
32
|
+
readonly status: number;
|
|
33
|
+
constructor(status: number, message: string);
|
|
34
|
+
}
|
|
35
|
+
export declare class OmniRouteClient {
|
|
36
|
+
readonly endpoint: string;
|
|
37
|
+
private readonly timeoutMs;
|
|
38
|
+
private apiKey;
|
|
39
|
+
private readonly metrics;
|
|
40
|
+
constructor(config?: OmniRouteConfig);
|
|
41
|
+
setApiKey(apiKey: string): void;
|
|
42
|
+
snapshotMetrics(): OmniRouteMetrics;
|
|
43
|
+
listCombos(signal?: AbortSignal): Promise<readonly OmniRouteCombo[]>;
|
|
44
|
+
chat(model: string, messages: readonly ChatMessage[], signal?: AbortSignal): Promise<ChatResult>;
|
|
45
|
+
private request;
|
|
46
|
+
private updateMetrics;
|
|
47
|
+
private safeBody;
|
|
48
|
+
private headerNumber;
|
|
49
|
+
private number;
|
|
50
|
+
private isRecord;
|
|
51
|
+
private combineSignals;
|
|
52
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export class OmniRouteError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
constructor(status, message) {
|
|
4
|
+
super(`OmniRoute ${status}: ${message}`);
|
|
5
|
+
this.status = status;
|
|
6
|
+
this.name = 'OmniRouteError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const DEFAULT_ENDPOINT = 'http://localhost:20128';
|
|
10
|
+
export class OmniRouteClient {
|
|
11
|
+
endpoint;
|
|
12
|
+
timeoutMs;
|
|
13
|
+
apiKey;
|
|
14
|
+
metrics = {
|
|
15
|
+
compression: { inputTokens: 0, compressedTokens: 0, ratio: 1, strategy: 'none', updatedAt: new Date().toISOString() },
|
|
16
|
+
fallback: { attempts: 0 },
|
|
17
|
+
requestCount: 0,
|
|
18
|
+
};
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
this.endpoint = (config.endpoint ?? process.env.OMNIROUTE_URL ?? DEFAULT_ENDPOINT).replace(/\/$/, '');
|
|
21
|
+
this.apiKey = config.apiKey ?? process.env.OMNIROUTE_API_KEY ?? '';
|
|
22
|
+
this.timeoutMs = config.timeoutMs ?? 120_000;
|
|
23
|
+
}
|
|
24
|
+
setApiKey(apiKey) {
|
|
25
|
+
this.apiKey = apiKey.trim();
|
|
26
|
+
}
|
|
27
|
+
snapshotMetrics() {
|
|
28
|
+
return structuredClone(this.metrics);
|
|
29
|
+
}
|
|
30
|
+
async listCombos(signal) {
|
|
31
|
+
const response = await this.request('/v1/combos', { method: 'GET', signal });
|
|
32
|
+
const payload = await response.json();
|
|
33
|
+
if (Array.isArray(payload))
|
|
34
|
+
return payload;
|
|
35
|
+
if (this.isRecord(payload) && Array.isArray(payload.combos))
|
|
36
|
+
return payload.combos;
|
|
37
|
+
throw new OmniRouteError(response.status, 'invalid combos response');
|
|
38
|
+
}
|
|
39
|
+
async chat(model, messages, signal) {
|
|
40
|
+
const response = await this.request('/chat/completions', {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
signal,
|
|
43
|
+
headers: { 'content-type': 'application/json' },
|
|
44
|
+
body: JSON.stringify({ model, messages, stream: false }),
|
|
45
|
+
});
|
|
46
|
+
const payload = await response.json();
|
|
47
|
+
if (!this.isRecord(payload) || !Array.isArray(payload.choices) || payload.choices.length === 0) {
|
|
48
|
+
throw new OmniRouteError(response.status, 'invalid chat response');
|
|
49
|
+
}
|
|
50
|
+
const choice = payload.choices[0];
|
|
51
|
+
const message = this.isRecord(choice) && this.isRecord(choice.message) ? choice.message : {};
|
|
52
|
+
const usage = this.isRecord(payload.usage) ? payload.usage : undefined;
|
|
53
|
+
return {
|
|
54
|
+
content: typeof message.content === 'string' ? message.content : '',
|
|
55
|
+
model,
|
|
56
|
+
usage: usage ? {
|
|
57
|
+
inputTokens: this.number(usage.prompt_tokens),
|
|
58
|
+
outputTokens: this.number(usage.completion_tokens),
|
|
59
|
+
totalTokens: this.number(usage.total_tokens),
|
|
60
|
+
} : undefined,
|
|
61
|
+
headers: response.headers,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async request(path, init) {
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
67
|
+
const signal = init.signal ? this.combineSignals(init.signal, controller.signal) : controller.signal;
|
|
68
|
+
const headers = new Headers(init.headers);
|
|
69
|
+
if (this.apiKey)
|
|
70
|
+
headers.set('authorization', `Bearer ${this.apiKey}`);
|
|
71
|
+
headers.set('x-omniharness-client', 'omniharness');
|
|
72
|
+
headers.set('x-omniharness-metrics', 'tokens,compression,fallback,quota');
|
|
73
|
+
this.metrics.requestCount += 1;
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(`${this.endpoint}${path}`, { ...init, headers, signal });
|
|
76
|
+
this.updateMetrics(response.headers);
|
|
77
|
+
if (!response.ok)
|
|
78
|
+
throw new OmniRouteError(response.status, await this.safeBody(response));
|
|
79
|
+
return response;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
updateMetrics(headers) {
|
|
86
|
+
const compression = this.metrics.compression;
|
|
87
|
+
const input = this.headerNumber(headers, 'x-omniroute-input-tokens');
|
|
88
|
+
const compressed = this.headerNumber(headers, 'x-omniroute-compressed-tokens');
|
|
89
|
+
if (input !== undefined && compressed !== undefined && input > 0) {
|
|
90
|
+
compression.inputTokens = input;
|
|
91
|
+
compression.compressedTokens = compressed;
|
|
92
|
+
compression.ratio = compressed / input;
|
|
93
|
+
compression.strategy = headers.get('x-omniroute-compression') ?? 'none';
|
|
94
|
+
compression.updatedAt = new Date().toISOString();
|
|
95
|
+
}
|
|
96
|
+
const fallback = this.metrics.fallback;
|
|
97
|
+
fallback.activeProvider = headers.get('x-omniroute-provider') ?? fallback.activeProvider;
|
|
98
|
+
fallback.lastFailure = headers.get('x-omniroute-fallback-reason') ?? fallback.lastFailure;
|
|
99
|
+
const attempts = this.headerNumber(headers, 'x-omniroute-fallback-attempts');
|
|
100
|
+
if (attempts !== undefined)
|
|
101
|
+
fallback.attempts = attempts;
|
|
102
|
+
const cooldown = headers.get('x-omniroute-cooldown-until');
|
|
103
|
+
if (cooldown)
|
|
104
|
+
fallback.cooldownUntil = cooldown;
|
|
105
|
+
const quota = this.headerNumber(headers, 'x-omniroute-remaining-quota');
|
|
106
|
+
if (quota !== undefined)
|
|
107
|
+
this.metrics.remainingQuota = quota;
|
|
108
|
+
}
|
|
109
|
+
async safeBody(response) {
|
|
110
|
+
const body = await response.text();
|
|
111
|
+
return body.slice(0, 500).replace(this.apiKey, '[REDACTED]');
|
|
112
|
+
}
|
|
113
|
+
headerNumber(headers, name) {
|
|
114
|
+
const value = headers.get(name);
|
|
115
|
+
if (value === null)
|
|
116
|
+
return undefined;
|
|
117
|
+
const parsed = Number(value);
|
|
118
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
119
|
+
}
|
|
120
|
+
number(value) {
|
|
121
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
122
|
+
}
|
|
123
|
+
isRecord(value) {
|
|
124
|
+
return typeof value === 'object' && value !== null;
|
|
125
|
+
}
|
|
126
|
+
combineSignals(first, second) {
|
|
127
|
+
const controller = new AbortController();
|
|
128
|
+
const abort = () => controller.abort();
|
|
129
|
+
if (first.aborted || second.aborted) {
|
|
130
|
+
controller.abort();
|
|
131
|
+
return controller.signal;
|
|
132
|
+
}
|
|
133
|
+
first.addEventListener('abort', abort, { once: true });
|
|
134
|
+
second.addEventListener('abort', abort, { once: true });
|
|
135
|
+
return controller.signal;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=omniRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"omniRoute.js","sourceRoot":"","sources":["../../src/config/omniRoute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AgentToolDeclaration, WorkspaceState } from '../types/index.js';
|
|
2
|
+
export interface SystemTools {
|
|
3
|
+
readFile: AgentToolDeclaration<{
|
|
4
|
+
path: string;
|
|
5
|
+
}, {
|
|
6
|
+
path: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}>;
|
|
9
|
+
writeFile: AgentToolDeclaration<{
|
|
10
|
+
path: string;
|
|
11
|
+
content: string;
|
|
12
|
+
}, {
|
|
13
|
+
path: string;
|
|
14
|
+
bytes: number;
|
|
15
|
+
}>;
|
|
16
|
+
runCommand: AgentToolDeclaration<{
|
|
17
|
+
command: string;
|
|
18
|
+
args?: readonly string[];
|
|
19
|
+
}, {
|
|
20
|
+
stdout: string;
|
|
21
|
+
stderr: string;
|
|
22
|
+
code: number;
|
|
23
|
+
}>;
|
|
24
|
+
indexWorkspace: AgentToolDeclaration<void, WorkspaceState>;
|
|
25
|
+
gitDiff: AgentToolDeclaration<void, string>;
|
|
26
|
+
}
|
|
27
|
+
export declare function createSystemTools(workspaceRoot: string, shellAllowed?: boolean): SystemTools;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const MAX_OUTPUT = 32_000;
|
|
8
|
+
const relativePath = z.string().min(1).refine((value) => !path.isAbsolute(value) && value !== '..' && !value.startsWith(`..${path.sep}`));
|
|
9
|
+
function within(root, target) {
|
|
10
|
+
const absoluteRoot = path.resolve(root);
|
|
11
|
+
const absoluteTarget = path.resolve(root, target);
|
|
12
|
+
const relative = path.relative(absoluteRoot, absoluteTarget);
|
|
13
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
14
|
+
throw new Error('path escapes workspace root');
|
|
15
|
+
return absoluteTarget;
|
|
16
|
+
}
|
|
17
|
+
export function createSystemTools(workspaceRoot, shellAllowed = false) {
|
|
18
|
+
const root = path.resolve(workspaceRoot);
|
|
19
|
+
const readFile = {
|
|
20
|
+
name: 'read_file', description: 'Read a UTF-8 file inside the workspace.', risk: 'low', inputSchema: { path: 'relative file path' },
|
|
21
|
+
async execute(input) {
|
|
22
|
+
const parsed = relativePath.parse(input.path);
|
|
23
|
+
const target = within(root, parsed);
|
|
24
|
+
return { path: parsed, content: await fs.readFile(target, 'utf8') };
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const writeFile = {
|
|
28
|
+
name: 'write_file', description: 'Write a UTF-8 file inside the workspace.', risk: 'high', inputSchema: { path: 'relative file path', content: 'file contents' },
|
|
29
|
+
async execute(input) {
|
|
30
|
+
const parsed = relativePath.parse(input.path);
|
|
31
|
+
const target = within(root, parsed);
|
|
32
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
33
|
+
await fs.writeFile(target, input.content, 'utf8');
|
|
34
|
+
return { path: parsed, bytes: Buffer.byteLength(input.content) };
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const runCommand = {
|
|
38
|
+
name: 'run_command', description: 'Run an approved executable in the workspace.', risk: 'high', inputSchema: { command: 'executable', args: 'arguments' },
|
|
39
|
+
async execute(input, signal) {
|
|
40
|
+
if (!shellAllowed)
|
|
41
|
+
throw new Error('shell execution is disabled by policy');
|
|
42
|
+
const result = await execFileAsync(input.command, [...(input.args ?? [])], { cwd: root, maxBuffer: MAX_OUTPUT, signal });
|
|
43
|
+
return { stdout: result.stdout.slice(0, MAX_OUTPUT), stderr: result.stderr.slice(0, MAX_OUTPUT), code: 0 };
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
const gitDiff = {
|
|
47
|
+
name: 'git_diff', description: 'Collect the current workspace git diff.', risk: 'low', inputSchema: {},
|
|
48
|
+
async execute(_input, signal) {
|
|
49
|
+
const result = await execFileAsync('git', ['diff', '--no-ext-diff', '--'], { cwd: root, maxBuffer: MAX_OUTPUT, signal });
|
|
50
|
+
return result.stdout.slice(0, MAX_OUTPUT);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const indexWorkspace = {
|
|
54
|
+
name: 'index_workspace', description: 'Recursively index non-hidden workspace files.', risk: 'low', inputSchema: {},
|
|
55
|
+
async execute() {
|
|
56
|
+
const files = [];
|
|
57
|
+
async function walk(directory) {
|
|
58
|
+
for (const entry of await fs.readdir(directory, { withFileTypes: true })) {
|
|
59
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules')
|
|
60
|
+
continue;
|
|
61
|
+
const target = path.join(directory, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
files.push({ path: path.relative(root, target), bytes: 0, kind: 'directory' });
|
|
64
|
+
await walk(target);
|
|
65
|
+
}
|
|
66
|
+
else if (entry.isFile()) {
|
|
67
|
+
const stat = await fs.stat(target);
|
|
68
|
+
files.push({ path: path.relative(root, target), bytes: stat.size, kind: 'file', extension: path.extname(entry.name) || undefined });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
await walk(root);
|
|
73
|
+
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
74
|
+
return { root, indexedAt: new Date().toISOString(), files, contextLocked: false };
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
return { readFile, writeFile, runCommand, indexWorkspace, gitDiff };
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=systemTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemTools.js","sourceRoot":"","sources":["../../src/tools/systemTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type TaskStatus = 'idle' | 'planning' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
|
|
2
|
+
export type ToolRisk = 'low' | 'medium' | 'high' | 'critical';
|
|
3
|
+
export interface WorkspaceFile {
|
|
4
|
+
path: string;
|
|
5
|
+
bytes: number;
|
|
6
|
+
kind: 'file' | 'directory';
|
|
7
|
+
extension?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface WorkspaceState {
|
|
10
|
+
root: string;
|
|
11
|
+
indexedAt: string | null;
|
|
12
|
+
files: readonly WorkspaceFile[];
|
|
13
|
+
gitBranch?: string;
|
|
14
|
+
gitDiffStat?: string;
|
|
15
|
+
contextLocked: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface CompressionTracker {
|
|
18
|
+
inputTokens: number;
|
|
19
|
+
compressedTokens: number;
|
|
20
|
+
ratio: number;
|
|
21
|
+
strategy: 'rtk' | 'caveman' | 'none';
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export interface FallbackTracker {
|
|
25
|
+
activeProvider?: string;
|
|
26
|
+
attempts: number;
|
|
27
|
+
lastFailure?: string;
|
|
28
|
+
cooldownUntil?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface OmniRouteMetrics {
|
|
31
|
+
compression: CompressionTracker;
|
|
32
|
+
fallback: FallbackTracker;
|
|
33
|
+
remainingQuota?: number;
|
|
34
|
+
requestCount: number;
|
|
35
|
+
}
|
|
36
|
+
export interface AgentToolDeclaration<TInput = unknown, TOutput = unknown> {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
risk: ToolRisk;
|
|
40
|
+
inputSchema: unknown;
|
|
41
|
+
execute(input: TInput, signal?: AbortSignal): Promise<TOutput>;
|
|
42
|
+
}
|
|
43
|
+
export interface HarnessState {
|
|
44
|
+
taskStatus: TaskStatus;
|
|
45
|
+
prompt: string;
|
|
46
|
+
workspace: WorkspaceState;
|
|
47
|
+
metrics: OmniRouteMetrics;
|
|
48
|
+
activeModel: string;
|
|
49
|
+
messages: readonly HarnessMessage[];
|
|
50
|
+
}
|
|
51
|
+
export interface HarnessMessage {
|
|
52
|
+
role: 'user' | 'assistant' | 'thought' | 'action' | 'error';
|
|
53
|
+
content: string;
|
|
54
|
+
createdAt: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { Box, Text, useApp, useInput, useStdout } from 'ink';
|
|
4
|
+
import Spinner from 'ink-spinner';
|
|
5
|
+
function widthOf(stdout) {
|
|
6
|
+
return Math.max(48, stdout.columns ?? 80);
|
|
7
|
+
}
|
|
8
|
+
function clip(text, width) {
|
|
9
|
+
return text.length <= width ? text : `${text.slice(0, Math.max(0, width - 1))}…`;
|
|
10
|
+
}
|
|
11
|
+
export function TerminalInterface({ engine }) {
|
|
12
|
+
const { exit } = useApp();
|
|
13
|
+
const { stdout } = useStdout();
|
|
14
|
+
const [width, setWidth] = useState(() => widthOf(stdout));
|
|
15
|
+
const [input, setInput] = useState('');
|
|
16
|
+
const [lines, setLines] = useState([]);
|
|
17
|
+
const [busy, setBusy] = useState(false);
|
|
18
|
+
const [error, setError] = useState();
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const onResize = () => setWidth(widthOf(stdout));
|
|
21
|
+
stdout.on('resize', onResize);
|
|
22
|
+
return () => { stdout.off('resize', onResize); };
|
|
23
|
+
}, [stdout]);
|
|
24
|
+
useInput((value, key) => {
|
|
25
|
+
if (key.ctrl && value === 'c') {
|
|
26
|
+
exit();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (key.return) {
|
|
30
|
+
const prompt = input.trim();
|
|
31
|
+
if (!prompt || busy)
|
|
32
|
+
return;
|
|
33
|
+
setInput('');
|
|
34
|
+
setBusy(true);
|
|
35
|
+
setError(undefined);
|
|
36
|
+
setLines((current) => [...current, { role: 'user', text: prompt }]);
|
|
37
|
+
void engine.run(prompt).then((answer) => {
|
|
38
|
+
setLines((current) => [...current, { role: 'assistant', text: answer }]);
|
|
39
|
+
}).catch((reason) => {
|
|
40
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
41
|
+
setError(message);
|
|
42
|
+
setLines((current) => [...current, { role: 'error', text: message }]);
|
|
43
|
+
}).finally(() => setBusy(false));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (key.backspace) {
|
|
47
|
+
setInput((current) => current.slice(0, -1));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!key.ctrl && !key.meta && value)
|
|
51
|
+
setInput((current) => current + value);
|
|
52
|
+
});
|
|
53
|
+
const contentWidth = Math.max(20, width - 6);
|
|
54
|
+
const metrics = engine.client.snapshotMetrics();
|
|
55
|
+
const compression = metrics.compression.inputTokens > 0 ? `${Math.round((1 - metrics.compression.ratio) * 100)}% via ${metrics.compression.strategy.toUpperCase()}` : 'pending';
|
|
56
|
+
const visibleLines = useMemo(() => lines.slice(-Math.max(3, (stdout.rows ?? 24) - 9)), [lines, stdout.rows]);
|
|
57
|
+
return _jsxs(Box, { flexDirection: "column", width: width, paddingX: 1, children: [_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: "cyan", children: "OmniHarness v2.0" }), _jsx(Text, { dimColor: true, children: "OmniRoute Local :20128" })] }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsxs(Box, { flexDirection: "column", width: Math.max(24, Math.floor(width * 0.27)), borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Text, { bold: true, children: "ROUTE" }), _jsxs(Text, { children: ["provider: ", metrics.fallback.activeProvider ?? 'auto'] }), _jsxs(Text, { children: ["compression: ", compression] }), _jsxs(Text, { children: ["cooldown: ", metrics.fallback.cooldownUntil ?? 'none'] }), _jsxs(Text, { children: ["requests: ", metrics.requestCount] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, marginLeft: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [visibleLines.length === 0 && _jsx(Text, { dimColor: true, children: "Describe a task to begin." }), visibleLines.map((line, index) => _jsxs(Text, { color: line.role === 'user' ? 'blue' : line.role === 'error' ? 'red' : undefined, children: [line.role === 'user' ? 'YOU ' : line.role === 'error' ? 'ERR ' : 'AGENT', " ", clip(line.text, contentWidth)] }, `${index}-${line.role}`)), busy && _jsxs(Text, { color: "cyan", children: [_jsx(Spinner, { type: "dots" }), " working through OmniRoute\u2026"] })] })] }), _jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: error ? 'red' : 'cyan', paddingX: 1, children: [_jsx(Text, { color: "cyan", children: "\u203A " }), _jsx(Text, { children: clip(input || 'type a task and press enter', contentWidth) })] }), _jsxs(Text, { dimColor: true, children: ["Ctrl+C quit \u00B7 model ", engine.state.activeModel] })] });
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=terminalInterface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminalInterface.js","sourceRoot":"","sources":["../../src/ui/terminalInterface.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omniharness-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "OmniHarness — local-first agent orchestration harness for OmniRoute.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "https://github.com/mattycigemp-crypto/omniharness.git"
|
|
9
10
|
},
|
|
10
11
|
"bin": {
|
|
11
|
-
"omniharness": "cli.
|
|
12
|
+
"omniharness": "cli.cjs"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
|
-
"cli.
|
|
15
|
-
"
|
|
15
|
+
"cli.cjs",
|
|
16
|
+
"dist/",
|
|
16
17
|
"README.md"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
package/cli.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// omniharness-cli launcher: runs the platform-specific prebuilt binary.
|
|
3
|
-
// The binary is self-contained; this shim only locates and spawns it.
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
const { spawnSync } = require('child_process');
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
const platform = process.platform;
|
|
11
|
-
const arch = process.arch;
|
|
12
|
-
const exe = platform === 'win32' ? 'omniharness.exe' : 'omniharness';
|
|
13
|
-
const binPath = path.join(__dirname, 'vendor', `${platform}-${arch}`, exe);
|
|
14
|
-
|
|
15
|
-
if (!fs.existsSync(binPath)) {
|
|
16
|
-
console.error(
|
|
17
|
-
`omniharness-cli: no prebuilt binary for ${platform}-${arch}.\n` +
|
|
18
|
-
'This package ships binaries for the platforms listed in its package.json ' +
|
|
19
|
-
'"os"/"cpu" fields. Build one with scripts/release-npm.sh.'
|
|
20
|
-
);
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const result = spawnSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
|
|
25
|
-
if (result.error) {
|
|
26
|
-
console.error(`omniharness-cli: failed to launch ${binPath}: ${result.error.message}`);
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
process.exit(result.status === null ? 1 : result.status);
|
|
Binary file
|