@jini-ai/agent-runtime 0.4.4 → 0.4.6
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 +5 -0
- package/dist/agent-protocol/acp/models.d.ts +11 -0
- package/dist/agent-protocol/acp/models.js +12 -3
- package/dist/capabilities.d.ts +1 -8
- package/dist/capabilities.js +8 -1
- package/dist/claude-code-models.d.ts +13 -1
- package/dist/claude-code-models.js +15 -17
- package/dist/claude-segment-usage.d.ts +9 -2
- package/dist/claude-segment-usage.js +20 -4
- package/dist/claude-stream.d.ts +4 -0
- package/dist/claude-stream.js +5 -1
- package/dist/defs/aider.js +1 -1
- package/dist/defs/amp.js +1 -1
- package/dist/defs/amr.js +1 -1
- package/dist/defs/antigravity.js +1 -1
- package/dist/defs/auggie.js +1 -1
- package/dist/defs/claude.d.ts +2 -0
- package/dist/defs/claude.js +11 -3
- package/dist/defs/cline.js +1 -1
- package/dist/defs/codebuddy.js +2 -2
- package/dist/defs/codex.js +1 -1
- package/dist/defs/copilot.js +1 -1
- package/dist/defs/crush.js +1 -1
- package/dist/defs/cursor-agent.js +2 -2
- package/dist/defs/deepseek.js +1 -1
- package/dist/defs/devin.js +1 -1
- package/dist/defs/droid.js +1 -1
- package/dist/defs/goose.js +1 -1
- package/dist/defs/grok-build.js +1 -1
- package/dist/defs/hermes.js +1 -1
- package/dist/defs/kilo.js +1 -1
- package/dist/defs/kimi.js +1 -1
- package/dist/defs/kiro.js +1 -1
- package/dist/defs/mimo.js +1 -1
- package/dist/defs/opencode.js +2 -2
- package/dist/defs/pi.js +1 -1
- package/dist/defs/qoder.js +1 -1
- package/dist/defs/qwen.js +1 -1
- package/dist/defs/reasonix.js +1 -1
- package/dist/defs/trae-cli.js +1 -1
- package/dist/defs/vibe.js +1 -1
- package/dist/detection.d.ts +28 -4
- package/dist/detection.js +82 -43
- package/dist/diagnostics.d.ts +6 -1
- package/dist/diagnostics.js +2 -2
- package/dist/env.js +1 -1
- package/dist/executables.d.ts +15 -9
- package/dist/executables.js +73 -65
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/invocation.d.ts +24 -2
- package/dist/invocation.js +19 -7
- package/dist/launch.d.ts +2 -1
- package/dist/launch.js +2 -2
- package/dist/model-discovery-adapters.d.ts +6 -2
- package/dist/model-discovery-adapters.js +64 -51
- package/dist/model-discovery-native.d.ts +14 -0
- package/dist/model-discovery-native.js +22 -0
- package/dist/model-discovery-sdk.js +1 -1
- package/dist/model-discovery-shared.d.ts +14 -0
- package/dist/model-discovery-shared.js +53 -0
- package/dist/model-discovery-types.d.ts +26 -0
- package/dist/model-discovery.d.ts +17 -22
- package/dist/model-discovery.js +18 -69
- package/dist/models.d.ts +9 -4
- package/dist/models.js +11 -11
- package/dist/probe-scheduler.d.ts +19 -0
- package/dist/probe-scheduler.js +30 -0
- package/dist/runtime-state.d.ts +41 -0
- package/dist/runtime-state.js +31 -0
- package/dist/types.d.ts +4 -0
- package/package.json +36 -9
package/dist/models.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defaultRuntimeState } from './runtime-state.js';
|
|
1
2
|
export const DEFAULT_MODEL_OPTION = {
|
|
2
3
|
id: 'default',
|
|
3
4
|
label: 'Default (CLI config)',
|
|
@@ -7,33 +8,32 @@ export const DEFAULT_MODEL_OPTION = {
|
|
|
7
8
|
// recent live list (refreshed every detectAgents() call) and additionally
|
|
8
9
|
// trust any value present in the static fallback. A model that's neither
|
|
9
10
|
// gets rejected so a stale or hostile value can't smuggle arbitrary flags.
|
|
10
|
-
|
|
11
|
-
const liveModelOrder = new Map();
|
|
11
|
+
// Host state carries these maps; legacy callers use defaultRuntimeState.
|
|
12
12
|
function liveModelCacheKey(agentId, scope) {
|
|
13
13
|
const trimmedScope = typeof scope === 'string' ? scope.trim() : '';
|
|
14
14
|
return trimmedScope ? `${agentId}\0${trimmedScope}` : agentId;
|
|
15
15
|
}
|
|
16
|
-
export function rememberLiveModels({ agentId, models }, { scope } = {}) {
|
|
16
|
+
export function rememberLiveModels({ agentId, models }, { scope, state = defaultRuntimeState } = {}) {
|
|
17
17
|
if (!Array.isArray(models))
|
|
18
18
|
return;
|
|
19
19
|
const ids = models
|
|
20
20
|
.map((m) => m && m.id)
|
|
21
21
|
.filter((id) => typeof id === 'string');
|
|
22
22
|
const key = liveModelCacheKey(agentId, scope);
|
|
23
|
-
liveModelCache.set(key, new Set(ids));
|
|
24
|
-
liveModelOrder.set(key, ids);
|
|
23
|
+
state.liveModelCache.set(key, new Set(ids));
|
|
24
|
+
state.liveModelOrder.set(key, ids);
|
|
25
25
|
}
|
|
26
|
-
export function getRememberedLiveModels({ agentId }, { scope } = {}) {
|
|
27
|
-
const ids = liveModelOrder.get(liveModelCacheKey(agentId, scope)) ?? [];
|
|
26
|
+
export function getRememberedLiveModels({ agentId }, { scope, state = defaultRuntimeState } = {}) {
|
|
27
|
+
const ids = state.liveModelOrder.get(liveModelCacheKey(agentId, scope)) ?? [];
|
|
28
28
|
return ids.map((id) => ({ id, label: id }));
|
|
29
29
|
}
|
|
30
30
|
export function preferFreshLiveModels({ freshModels, rememberedModels }) {
|
|
31
31
|
return freshModels.length > 0 ? freshModels : rememberedModels;
|
|
32
32
|
}
|
|
33
|
-
export function isKnownModel({ def, modelId }, { scope } = {}) {
|
|
33
|
+
export function isKnownModel({ def, modelId }, { scope, state = defaultRuntimeState } = {}) {
|
|
34
34
|
if (!modelId)
|
|
35
35
|
return false;
|
|
36
|
-
const live = liveModelCache.get(liveModelCacheKey(def.id, scope));
|
|
36
|
+
const live = state.liveModelCache.get(liveModelCacheKey(def.id, scope));
|
|
37
37
|
if (live && live.has(modelId))
|
|
38
38
|
return true;
|
|
39
39
|
if (Array.isArray(def.fallbackModels)) {
|
|
@@ -49,7 +49,7 @@ export function isKnownModel({ def, modelId }, { scope } = {}) {
|
|
|
49
49
|
// surfaced to the UI, then fall back to the def's first concrete fallback
|
|
50
50
|
// id so the spawn layer always has a real model to forward. Defs that DO
|
|
51
51
|
// list 'default' (the common case) are left untouched.
|
|
52
|
-
export function resolveModelForAgent({ def, resolved }, { env = process.env, liveModelScope } = {}) {
|
|
52
|
+
export function resolveModelForAgent({ def, resolved }, { env = process.env, liveModelScope, state = defaultRuntimeState } = {}) {
|
|
53
53
|
if (resolved && resolved !== 'default')
|
|
54
54
|
return resolved;
|
|
55
55
|
// Host-process env override. Lets an operator pin a different fallback
|
|
@@ -66,7 +66,7 @@ export function resolveModelForAgent({ def, resolved }, { env = process.env, liv
|
|
|
66
66
|
const fallbacks = def.fallbackModels;
|
|
67
67
|
if (fallbacks.some((m) => m.id === 'default'))
|
|
68
68
|
return resolved;
|
|
69
|
-
const liveModels = liveModelOrder.get(liveModelCacheKey(def.id, liveModelScope)) ?? [];
|
|
69
|
+
const liveModels = state.liveModelOrder.get(liveModelCacheKey(def.id, liveModelScope)) ?? [];
|
|
70
70
|
const firstLive = liveModels[0];
|
|
71
71
|
if (firstLive)
|
|
72
72
|
return firstLive;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type Priority = 'version' | 'metadata';
|
|
2
|
+
/** All metadata process adapters share one process-wide slot. Version checks precede queued
|
|
3
|
+
* metadata, so expensive discovery cannot delay cheap availability checks. Actual chat runs
|
|
4
|
+
* never use this queue. A slot is held until the child adapter settles, including cancellation.
|
|
5
|
+
* @complexity O(q) queued selection, bounded by the runtime registry's probe count. */
|
|
6
|
+
export declare function createProbeScheduler(_input: Record<string, never>, _options?: Record<string, never>): <T>({ work }: {
|
|
7
|
+
work: () => Promise<T>;
|
|
8
|
+
}, { priority, signal }?: {
|
|
9
|
+
priority?: Priority;
|
|
10
|
+
signal?: AbortSignal | undefined;
|
|
11
|
+
}) => Promise<T>;
|
|
12
|
+
export declare const scheduleProbeProcess: <T>({ work }: {
|
|
13
|
+
work: () => Promise<T>;
|
|
14
|
+
}, { priority, signal }?: {
|
|
15
|
+
priority?: Priority;
|
|
16
|
+
signal?: AbortSignal | undefined;
|
|
17
|
+
}) => Promise<T>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=probe-scheduler.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** All metadata process adapters share one process-wide slot. Version checks precede queued
|
|
2
|
+
* metadata, so expensive discovery cannot delay cheap availability checks. Actual chat runs
|
|
3
|
+
* never use this queue. A slot is held until the child adapter settles, including cancellation.
|
|
4
|
+
* @complexity O(q) queued selection, bounded by the runtime registry's probe count. */
|
|
5
|
+
export function createProbeScheduler(_input, _options = {}) {
|
|
6
|
+
const queue = [];
|
|
7
|
+
let running = false;
|
|
8
|
+
function drain() {
|
|
9
|
+
if (running || !queue.length)
|
|
10
|
+
return;
|
|
11
|
+
const version = queue.findIndex(entry => entry.priority === 'version');
|
|
12
|
+
const entry = queue.splice(version < 0 ? 0 : version, 1)[0];
|
|
13
|
+
running = true;
|
|
14
|
+
entry.start();
|
|
15
|
+
}
|
|
16
|
+
return function schedule({ work }, { priority = 'metadata', signal } = {}) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
queue.push({ priority, start: () => {
|
|
19
|
+
Promise.resolve().then(() => {
|
|
20
|
+
if (signal?.aborted)
|
|
21
|
+
throw new Error('Probe cancelled');
|
|
22
|
+
return work();
|
|
23
|
+
}).then(resolve, reject).finally(() => { running = false; drain(); });
|
|
24
|
+
} });
|
|
25
|
+
drain();
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export const scheduleProbeProcess = createProbeScheduler({});
|
|
30
|
+
//# sourceMappingURL=probe-scheduler.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Mutable runtime data belongs to one host. Compatibility functions use defaultRuntimeState. */
|
|
2
|
+
import type { RuntimeAgentDef, RuntimeCapabilityMap, RuntimeModelOption, DetectedAgent } from './types.js';
|
|
3
|
+
import type { ModelCacheEntry, ModelDiscoveryDeps } from './model-discovery-types.js';
|
|
4
|
+
export interface AgentRuntimeState {
|
|
5
|
+
/** One in-flight or settled complete detection per launch scope until explicit Rescan. */
|
|
6
|
+
readonly detections: Map<string, Promise<DetectedAgent>>;
|
|
7
|
+
readonly capabilities: Map<string, RuntimeCapabilityMap>;
|
|
8
|
+
/** One in-flight or settled `--help` probe per def id + launch path, so a run never re-spawns it. */
|
|
9
|
+
readonly capabilityProbes: Map<string, Promise<void>>;
|
|
10
|
+
readonly liveModelCache: Map<string, Set<string>>;
|
|
11
|
+
readonly liveModelOrder: Map<string, string[]>;
|
|
12
|
+
readonly claudeModels: Map<string, {
|
|
13
|
+
expiresAt: number;
|
|
14
|
+
value: Promise<readonly RuntimeModelOption[] | null>;
|
|
15
|
+
}>;
|
|
16
|
+
discoveryDeps?: ModelDiscoveryDeps;
|
|
17
|
+
readonly modelCatalog: Map<string, ModelCacheEntry>;
|
|
18
|
+
readonly executable: {
|
|
19
|
+
/** Env var names consulted by detection-home/resource-root resolution. Overridable via `configureExecutableResolutionEnv`. */
|
|
20
|
+
envNames: {
|
|
21
|
+
agentHomeEnvVar: string;
|
|
22
|
+
resourceRootEnvVar: string;
|
|
23
|
+
};
|
|
24
|
+
toolchainKey: string | null;
|
|
25
|
+
toolchainDirs: string[] | null;
|
|
26
|
+
toolchainDirsAt: number;
|
|
27
|
+
};
|
|
28
|
+
/** Clear settled caches after host operations finish; retain its configured env names. */
|
|
29
|
+
clear(required: Record<string, never>, optional: Record<string, never>): void;
|
|
30
|
+
}
|
|
31
|
+
/** Independent state, including in-flight probes, for each embedding host.
|
|
32
|
+
* Returns empty owned maps; no I/O. @complexity O(1) initialization; retained data grows with probes. */
|
|
33
|
+
export declare function createAgentRuntimeState(_required: Record<string, never>, _optional?: Record<string, never>): AgentRuntimeState;
|
|
34
|
+
export declare const defaultRuntimeState: AgentRuntimeState;
|
|
35
|
+
/** Bind the agent argument builder to the same capability state detection and launch use.
|
|
36
|
+
* Returns a definition copy without mutating the registry. @complexity O(1). */
|
|
37
|
+
export declare function bindRuntimeAgentDef({ def, state }: {
|
|
38
|
+
def: RuntimeAgentDef;
|
|
39
|
+
state: AgentRuntimeState;
|
|
40
|
+
}, _optional?: Record<string, never>): RuntimeAgentDef;
|
|
41
|
+
//# sourceMappingURL=runtime-state.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Independent state, including in-flight probes, for each embedding host.
|
|
2
|
+
* Returns empty owned maps; no I/O. @complexity O(1) initialization; retained data grows with probes. */
|
|
3
|
+
export function createAgentRuntimeState(_required, _optional = {}) {
|
|
4
|
+
const state = {
|
|
5
|
+
detections: new Map(), capabilities: new Map(), capabilityProbes: new Map(), liveModelCache: new Map(), liveModelOrder: new Map(),
|
|
6
|
+
claudeModels: new Map(), modelCatalog: new Map(),
|
|
7
|
+
executable: { envNames: { agentHomeEnvVar: 'AGENT_RUNTIME_HOME', resourceRootEnvVar: 'AGENT_RUNTIME_RESOURCE_ROOT' }, toolchainKey: null, toolchainDirs: null, toolchainDirsAt: 0 },
|
|
8
|
+
clear() {
|
|
9
|
+
state.detections.clear();
|
|
10
|
+
state.capabilities.clear();
|
|
11
|
+
state.capabilityProbes.clear();
|
|
12
|
+
state.liveModelCache.clear();
|
|
13
|
+
state.liveModelOrder.clear();
|
|
14
|
+
state.claudeModels.clear();
|
|
15
|
+
state.modelCatalog.clear();
|
|
16
|
+
state.executable.toolchainKey = null;
|
|
17
|
+
state.executable.toolchainDirs = null;
|
|
18
|
+
state.executable.toolchainDirsAt = 0;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
export const defaultRuntimeState = createAgentRuntimeState({});
|
|
24
|
+
/** Bind the agent argument builder to the same capability state detection and launch use.
|
|
25
|
+
* Returns a definition copy without mutating the registry. @complexity O(1). */
|
|
26
|
+
export function bindRuntimeAgentDef({ def, state }, _optional = {}) {
|
|
27
|
+
return { ...def, buildArgs: (required, optional = {}) => def.buildArgs(required, {
|
|
28
|
+
...optional, options: { ...optional.options, capabilities: state.capabilities.get(def.id) ?? {} },
|
|
29
|
+
}) };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=runtime-state.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -75,6 +75,8 @@ export type RuntimeReasoningInModelId = {
|
|
|
75
75
|
levels: readonly RuntimeReasoningOption[];
|
|
76
76
|
};
|
|
77
77
|
export type RuntimeBuildOptions = {
|
|
78
|
+
/** Host-scoped capability flags; absent retains the published compatibility cache. */
|
|
79
|
+
capabilities?: RuntimeCapabilityMap;
|
|
78
80
|
model?: string | null;
|
|
79
81
|
reasoning?: string | null;
|
|
80
82
|
permissionMode?: 'bypass' | 'restricted';
|
|
@@ -291,6 +293,8 @@ export type RuntimeAgentDef = Partial<AgentModelDiscoveryPort> & {
|
|
|
291
293
|
runtimeContext?: RuntimeContext;
|
|
292
294
|
}) => string[];
|
|
293
295
|
streamFormat: string;
|
|
296
|
+
/** Reported money spans a session or one run; absent preserves per-run adapter behavior. */
|
|
297
|
+
usageCostBasis?: 'session' | 'run';
|
|
294
298
|
fallbackBins?: string[];
|
|
295
299
|
versionProbeTimeoutMs?: number;
|
|
296
300
|
helpArgs?: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/agent-runtime",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "Coding-agent runtime adapters: runtime registry, detection, launch, stream parsers, and the ACP/pi-rpc subprocess transport.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,21 @@
|
|
|
16
16
|
".": "node",
|
|
17
17
|
"./providers/tool-turn": "node",
|
|
18
18
|
"./model-catalog/cache": "universal",
|
|
19
|
-
"./providers/sse-decode": "universal"
|
|
19
|
+
"./providers/sse-decode": "universal",
|
|
20
|
+
"./model-discovery": "node"
|
|
21
|
+
},
|
|
22
|
+
"isolation": {
|
|
23
|
+
"forbidden": {
|
|
24
|
+
"./model-discovery": [
|
|
25
|
+
"node:child_process",
|
|
26
|
+
"child_process",
|
|
27
|
+
"node:fs",
|
|
28
|
+
"fs",
|
|
29
|
+
"./model-discovery-adapters.js",
|
|
30
|
+
"./model-discovery-native.js",
|
|
31
|
+
"./model-discovery-sdk.js"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
20
34
|
}
|
|
21
35
|
},
|
|
22
36
|
"type": "module",
|
|
@@ -43,6 +57,11 @@
|
|
|
43
57
|
"types": "./dist/providers/sse-decode.d.ts",
|
|
44
58
|
"import": "./dist/providers/sse-decode.js",
|
|
45
59
|
"default": "./dist/providers/sse-decode.js"
|
|
60
|
+
},
|
|
61
|
+
"./model-discovery": {
|
|
62
|
+
"types": "./dist/model-discovery.d.ts",
|
|
63
|
+
"import": "./dist/model-discovery.js",
|
|
64
|
+
"default": "./dist/model-discovery.js"
|
|
46
65
|
}
|
|
47
66
|
},
|
|
48
67
|
"typesVersions": {
|
|
@@ -55,6 +74,9 @@
|
|
|
55
74
|
],
|
|
56
75
|
"providers/sse-decode": [
|
|
57
76
|
"./dist/providers/sse-decode.d.ts"
|
|
77
|
+
],
|
|
78
|
+
"model-discovery": [
|
|
79
|
+
"./dist/model-discovery.d.ts"
|
|
58
80
|
]
|
|
59
81
|
}
|
|
60
82
|
},
|
|
@@ -77,20 +99,25 @@
|
|
|
77
99
|
"devDependencies": {
|
|
78
100
|
"@vitest/coverage-v8": "^2.1.9",
|
|
79
101
|
"@jini-ai/core": "^0.4.0",
|
|
80
|
-
"@jini-ai/
|
|
81
|
-
"@jini-ai/platform": "^0.5.
|
|
82
|
-
"@jini-ai/protocol": "^0.4.
|
|
102
|
+
"@jini-ai/integrations": "^0.4.2",
|
|
103
|
+
"@jini-ai/platform": "^0.5.5",
|
|
104
|
+
"@jini-ai/protocol": "^0.4.4",
|
|
105
|
+
"@jini-ai/oauth": "^0.2.2"
|
|
83
106
|
},
|
|
84
107
|
"dependencies": {
|
|
85
|
-
"@jini-ai/core": "^0.4.
|
|
108
|
+
"@jini-ai/core": "^0.4.4"
|
|
86
109
|
},
|
|
87
110
|
"peerDependencies": {
|
|
111
|
+
"@jini-ai/integrations": "^0.4.2",
|
|
88
112
|
"@github/copilot-sdk": "*",
|
|
89
|
-
"@jini-ai/oauth": "^0.2.
|
|
90
|
-
"@jini-ai/platform": "^0.5.
|
|
91
|
-
"@jini-ai/protocol": "^0.4.
|
|
113
|
+
"@jini-ai/oauth": "^0.2.2",
|
|
114
|
+
"@jini-ai/platform": "^0.5.5",
|
|
115
|
+
"@jini-ai/protocol": "^0.4.4"
|
|
92
116
|
},
|
|
93
117
|
"peerDependenciesMeta": {
|
|
118
|
+
"@jini-ai/integrations": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
94
121
|
"@github/copilot-sdk": {
|
|
95
122
|
"optional": true
|
|
96
123
|
},
|