@gaia-ai/core 0.6.0 → 0.6.1
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 -2
- package/dist/src/cli/load-gaia-config.js +8 -1
- package/dist/src/core/exec.d.ts +1 -1
- package/dist/src/core/exec.js +1 -1
- package/dist/src/index.d.ts +1 -9
- package/dist/src/index.js +12 -6
- package/dist/src/plugins/discover-addons.d.ts +19 -8
- package/dist/src/plugins/discover-addons.js +13 -3
- package/dist/src/plugins/preset.d.ts +30 -12
- package/dist/src/plugins/preset.js +10 -0
- package/package.json +4 -5
- package/dist/src/plugins/agent/agent.d.ts +0 -61
- package/dist/src/plugins/agent/agent.js +0 -11
- package/dist/src/plugins/auth/basic.d.ts +0 -12
- package/dist/src/plugins/auth/basic.js +0 -37
- package/dist/src/plugins/builtins-preset.d.ts +0 -5
- package/dist/src/plugins/builtins-preset.js +0 -32
- package/dist/src/plugins/executor/executor.d.ts +0 -104
- package/dist/src/plugins/executor/executor.js +0 -1
- package/dist/src/plugins/plugins.d.ts +0 -60
- package/dist/src/plugins/plugins.js +0 -42
- package/dist/src/plugins/registry-exports.d.ts +0 -6
- package/dist/src/plugins/registry-exports.js +0 -6
- package/dist/src/plugins/remote/drupal.d.ts +0 -40
- package/dist/src/plugins/remote/drupal.js +0 -393
- package/dist/src/plugins/remote/fake.d.ts +0 -113
- package/dist/src/plugins/remote/fake.js +0 -247
- package/dist/src/plugins/remote/remote.d.ts +0 -203
- package/dist/src/plugins/remote/remote.js +0 -1
- package/dist/src/plugins/workspace/fake.d.ts +0 -6
- package/dist/src/plugins/workspace/fake.js +0 -16
- package/dist/src/plugins/workspace/git.d.ts +0 -37
- package/dist/src/plugins/workspace/git.js +0 -89
- package/dist/src/plugins/workspace/instructions.d.ts +0 -6
- package/dist/src/plugins/workspace/instructions.js +0 -16
- package/dist/src/plugins/workspace/workspace.d.ts +0 -35
- package/dist/src/plugins/workspace/workspace.js +0 -1
- package/dist/src/plugins-index.d.ts +0 -1
- package/dist/src/plugins-index.js +0 -1
- package/dist/src/types.d.ts +0 -65
- package/dist/src/types.js +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# @gaia-ai/core
|
|
2
2
|
|
|
3
|
-
GAIA
|
|
3
|
+
GAIA surface-agnostic kernel: host contract, split-config helpers, addon preset/discovery machinery, shared primitives.
|
|
4
4
|
|
|
5
|
-
Part of the GAIA
|
|
5
|
+
Part of the GAIA CLI. Install the meta package `@gaia-ai/gaia` to get the `gaia` CLI with all addons. Source: https://git.key-tec.de/keytec/gaia (gaia-cli/).
|
|
@@ -80,7 +80,14 @@ export async function loadGaiaConfig(host, opts = {}) {
|
|
|
80
80
|
const site = isRecord(raw.site) ? raw.site : {};
|
|
81
81
|
const baseUrl = typeof site.base_url === 'string' ? site.base_url : '';
|
|
82
82
|
if (baseUrl.trim() === '') {
|
|
83
|
-
|
|
83
|
+
// GAIA-218 (AC-9): a legible failure that names the resolved connection path
|
|
84
|
+
// and the file that was expected to supply `site.base_url`, so a mis-resolved
|
|
85
|
+
// or empty connection is diagnosable — never a downstream plugin error (auth
|
|
86
|
+
// no longer lives in the engine config, so no plugin resolution runs here).
|
|
87
|
+
const expected = resolution.fallback
|
|
88
|
+
? 'the shipped machine-context fallback resolved no base_url — run `gaia conductor init` or create ~/.gaia/gaia.config.js'
|
|
89
|
+
: 'expected a gaia.config.js (project ./.gaia/gaia.config.js or home ~/.gaia/gaia.config.js) declaring site.base_url';
|
|
90
|
+
throw new Error(`gaia connection config requires site.base_url — resolved ${configPath}; ${expected}`);
|
|
84
91
|
}
|
|
85
92
|
const jsonapiPrefix = typeof site.jsonapi_prefix === 'string' && site.jsonapi_prefix.trim() !== ''
|
|
86
93
|
? site.jsonapi_prefix
|
package/dist/src/core/exec.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare class CommandRunner {
|
|
|
28
28
|
/**
|
|
29
29
|
* Replace the module-level singleton runner used by {@link exec}.
|
|
30
30
|
*
|
|
31
|
-
* Note: out-of-package plugins (e.g. `@gaia-ai/
|
|
31
|
+
* Note: out-of-package plugins (e.g. `@gaia-ai/addon-herdr`) import `exec` via
|
|
32
32
|
* the `@gaia-ai/gaia/plugin` barrel, which resolves to the built `dist/`
|
|
33
33
|
* copy of this module. This means `setDefaultCommandRunner` only shares the
|
|
34
34
|
* runner with those plugins when the conductor itself runs from `dist`
|
package/dist/src/core/exec.js
CHANGED
|
@@ -64,7 +64,7 @@ let defaultRunner = new CommandRunner(noopLogger);
|
|
|
64
64
|
/**
|
|
65
65
|
* Replace the module-level singleton runner used by {@link exec}.
|
|
66
66
|
*
|
|
67
|
-
* Note: out-of-package plugins (e.g. `@gaia-ai/
|
|
67
|
+
* Note: out-of-package plugins (e.g. `@gaia-ai/addon-herdr`) import `exec` via
|
|
68
68
|
* the `@gaia-ai/gaia/plugin` barrel, which resolves to the built `dist/`
|
|
69
69
|
* copy of this module. This means `setDefaultCommandRunner` only shares the
|
|
70
70
|
* runner with those plugins when the conductor itself runs from `dist`
|
package/dist/src/index.d.ts
CHANGED
|
@@ -11,14 +11,6 @@ export { CommandRunner, ExecError, exec, setDefaultCommandRunner, } from './core
|
|
|
11
11
|
export { type ConductorLogger, createLogger } from './core/logger.js';
|
|
12
12
|
export { shellQuote } from './core/shell.js';
|
|
13
13
|
export { DEFAULT_SLUG_MAX_LENGTH, slugify } from './core/slug.js';
|
|
14
|
-
export { type AgentFootprint, emptyAgentFootprint, type GaiaAgent, } from './plugins/agent/agent.js';
|
|
15
14
|
export { discoverAddons, type ResolvedConductorSlots, resolveConductorSlots, } from './plugins/discover-addons.js';
|
|
16
|
-
export type
|
|
17
|
-
export type { AgentCandidate, AgentPlugin, ExecutorDeps, ExecutorPlugin, RemotePlugin, ResolvedAgent, WorkspacePlugin, } from './plugins/plugins.js';
|
|
18
|
-
export { selectAgent, selectAgents } from './plugins/plugins.js';
|
|
19
|
-
export { type AddonEntry, type CommandDescriptor, type DiscoveredContributions, emptyContributions, type GaiaPreset, type GaiaSurface, PRESET_FUNCTION_KEYS, SURFACE_KEYS, } from './plugins/preset.js';
|
|
20
|
-
export type * from './plugins/remote/remote.js';
|
|
21
|
-
export { loadInstructions } from './plugins/workspace/instructions.js';
|
|
22
|
-
export type { EnsuredWorkspace, GaiaWorkspace, } from './plugins/workspace/workspace.js';
|
|
23
|
-
export type * from './types.js';
|
|
15
|
+
export { type AddonEntry, type CommandDescriptor, type DiscoveredContributions, emptyContributions, type GaiaPreset, type GaiaSurface, type OpaqueAccumulator, PRESET_FUNCTION_KEYS, SURFACE_KEYS, } from './plugins/preset.js';
|
|
24
16
|
export { type ExpandedLoad, expandLoad, type InputDecl, parseStepValues, readSkillWhen, type SkillContract, type SkillWhen, StepContractError, type StepValues, type Triple, validateLoad, type WhenValue, WORKFLOW_STEPS, type WorkflowStep, } from './workflow/step-contract.js';
|
package/dist/src/index.js
CHANGED
|
@@ -9,14 +9,20 @@ export { CommandRunner, ExecError, exec, setDefaultCommandRunner, } from './core
|
|
|
9
9
|
export { createLogger } from './core/logger.js';
|
|
10
10
|
export { shellQuote } from './core/shell.js';
|
|
11
11
|
export { DEFAULT_SLUG_MAX_LENGTH, slugify } from './core/slug.js';
|
|
12
|
-
export { emptyAgentFootprint, } from './plugins/agent/agent.js';
|
|
13
12
|
// GAIA-215: the Storybook-style preset contract + the shared addon discovery.
|
|
13
|
+
// GAIA-224 (Finding 6): SURFACE-AGNOSTIC only. The conductor-surface interfaces
|
|
14
|
+
// (`GaiaRemote`/`GaiaExecutor`/`GaiaWorkspace`/`GaiaAgent`, the four `*Plugin`
|
|
15
|
+
// interfaces, `ExecutorDeps`, `AgentCandidate`/`ResolvedAgent`, the `select*`
|
|
16
|
+
// selectors), the config contract (`ConductorSettings`/`ConductorFileConfig`/
|
|
17
|
+
// `ConductorEngineConfig`) and every built-in IMPLEMENTATION have moved out of
|
|
18
|
+
// this kernel — the contract to `@gaia-ai/conductor` (subpath
|
|
19
|
+
// `@gaia-ai/conductor/contract`), the impls to their own addons
|
|
20
|
+
// (`@gaia-ai/addon-remote-drupal`, `@gaia-ai/addon-workspace-git`,
|
|
21
|
+
// `@gaia-ai/addon-auth-basic`, `@gaia-ai/addon-fake`). `loadInstructions` moved to
|
|
22
|
+
// `@gaia-ai/addon-workspace-git`. Core ships NO plugin implementations.
|
|
14
23
|
export { discoverAddons, resolveConductorSlots, } from './plugins/discover-addons.js';
|
|
15
|
-
export { selectAgent, selectAgents } from './plugins/plugins.js';
|
|
16
24
|
export { emptyContributions, PRESET_FUNCTION_KEYS, SURFACE_KEYS, } from './plugins/preset.js';
|
|
17
25
|
// GAIA-194 AC-2: the agent-host contract (`AgentLaunchHost` / `HostedAgent` /
|
|
18
|
-
// `supportsAgentHost`)
|
|
19
|
-
// seam (`@gaia-ai/
|
|
20
|
-
// the conductor engine contract only.
|
|
21
|
-
export { loadInstructions } from './plugins/workspace/instructions.js';
|
|
26
|
+
// `supportsAgentHost`) is likewise NOT here — it is the TUI renderer's own plugin
|
|
27
|
+
// seam (`@gaia-ai/addon-gaia-ui`), and herdr types its impl locally.
|
|
22
28
|
export { expandLoad, parseStepValues, readSkillWhen, StepContractError, validateLoad, WORKFLOW_STEPS, } from './workflow/step-contract.js';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ConductorLogger } from '../core/logger.js';
|
|
2
|
-
import type { AgentCandidate, ExecutorPlugin, RemotePlugin, WorkspacePlugin } from './plugins.js';
|
|
3
2
|
import { type AddonEntry, type DiscoveredContributions, type GaiaSurface } from './preset.js';
|
|
4
3
|
/**
|
|
5
4
|
* Discover + accumulate the `entries` for one `surface`. `bases` is the
|
|
@@ -11,12 +10,24 @@ import { type AddonEntry, type DiscoveredContributions, type GaiaSurface } from
|
|
|
11
10
|
export declare function discoverAddons(entries: AddonEntry[] | undefined, surface: GaiaSurface, bases: string[], opts?: {
|
|
12
11
|
logger?: ConductorLogger;
|
|
13
12
|
}): Promise<DiscoveredContributions>;
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The resolved conductor slots (last-wins singletons + agent candidate list).
|
|
15
|
+
* Generic over the four element types so the kernel stays surface-agnostic while
|
|
16
|
+
* the caller keeps full type-safety: the engine passes its narrowed
|
|
17
|
+
* `ConductorContributions` (see `@gaia-ai/conductor`'s
|
|
18
|
+
* `narrowConductorContributions`) and gets `RemotePlugin`/`ExecutorPlugin`/
|
|
19
|
+
* `WorkspacePlugin`/`AgentCandidate` back.
|
|
20
|
+
*/
|
|
21
|
+
export interface ResolvedConductorSlots<R = unknown, E = unknown, W = unknown, A = unknown> {
|
|
22
|
+
remote?: R;
|
|
23
|
+
executor?: E;
|
|
24
|
+
workspace?: W;
|
|
25
|
+
agents: A[];
|
|
20
26
|
}
|
|
21
27
|
/** Resolve discovered conductor contributions into the four engine slots. */
|
|
22
|
-
export declare function resolveConductorSlots
|
|
28
|
+
export declare function resolveConductorSlots<R, E, W, A>(contributions: {
|
|
29
|
+
remotes: R[];
|
|
30
|
+
executors: E[];
|
|
31
|
+
workspaces: W[];
|
|
32
|
+
agents: A[];
|
|
33
|
+
}, logger?: ConductorLogger): ResolvedConductorSlots<R, E, W, A>;
|
|
@@ -19,6 +19,13 @@
|
|
|
19
19
|
// export adapted as a single contribution, logged) → run the surface's
|
|
20
20
|
// accumulators with the entry's `with` → for `agents`, attach the entry's
|
|
21
21
|
// `priority`. The runtime `.kind` guard is retained at singleton resolution.
|
|
22
|
+
//
|
|
23
|
+
// GAIA-224 (Finding 6, decision 7): surface-AGNOSTIC. The per-surface
|
|
24
|
+
// accumulators are opaque `unknown[]` here (their element types belong to the
|
|
25
|
+
// surface owner — `@gaia-ai/conductor` for the conductor surface), so this module
|
|
26
|
+
// keeps zero `@gaia-ai/*` edges. Everything it needs from a contribution is
|
|
27
|
+
// structural: the `.kind` tag for the singleton guard, `.id` for the warn line,
|
|
28
|
+
// and `.priority` for the agent-candidate attach.
|
|
22
29
|
import { pathToFileURL } from 'node:url';
|
|
23
30
|
import { resolveModuleEslintStyle } from '../cli/resolve-module.js';
|
|
24
31
|
import { emptyContributions, PRESET_FUNCTION_KEYS, SURFACE_KEYS, } from './preset.js';
|
|
@@ -205,12 +212,15 @@ function resolveSingleton(list, kind, logger) {
|
|
|
205
212
|
return undefined;
|
|
206
213
|
const warn = warnFrom(logger);
|
|
207
214
|
if (list.length > 1) {
|
|
208
|
-
const ids = list
|
|
215
|
+
const ids = list
|
|
216
|
+
.map((p) => p.id ?? '<?>')
|
|
217
|
+
.join(', ');
|
|
209
218
|
warn(`${kind}: ${list.length} addons contributed a ${kind} ([${ids}]); using the last (override wins)`);
|
|
210
219
|
}
|
|
211
220
|
const picked = list[list.length - 1];
|
|
212
|
-
|
|
213
|
-
|
|
221
|
+
const pickedKind = picked.kind;
|
|
222
|
+
if (pickedKind !== kind) {
|
|
223
|
+
throw new Error(`addon contributed a '${String(pickedKind)}' into the ${kind} slot`);
|
|
214
224
|
}
|
|
215
225
|
return picked;
|
|
216
226
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { DropSHPlugin } from 'dropsh/plugin';
|
|
2
|
-
import type { AgentCandidate, ExecutorPlugin, RemotePlugin, WorkspacePlugin } from './plugins.js';
|
|
3
|
-
import type { Ticket } from './remote/remote.js';
|
|
4
2
|
/**
|
|
5
3
|
* A lazy command pointer (moved here from the host, GAIA-201, + `describe`). The
|
|
6
4
|
* command surface accumulates DESCRIPTORS — never constructed command plugins —
|
|
@@ -35,8 +33,15 @@ export type AddonEntry = string | {
|
|
|
35
33
|
with?: unknown;
|
|
36
34
|
/** Alias for `with`. */
|
|
37
35
|
options?: unknown;
|
|
38
|
-
/**
|
|
39
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Agent-surface only: the static per-ticket priority (see the conductor
|
|
38
|
+
* surface's `selectAgent`). The ticket type belongs to the conductor
|
|
39
|
+
* surface, so the kernel types the parameter as `never` — that makes ANY
|
|
40
|
+
* concretely-typed `(ticket: Ticket) => number` assignable here (a `never`
|
|
41
|
+
* parameter is contravariantly assignable to every parameter type) while
|
|
42
|
+
* keeping this module free of a conductor import.
|
|
43
|
+
*/
|
|
44
|
+
priority?: (ticket: never) => number;
|
|
40
45
|
};
|
|
41
46
|
/**
|
|
42
47
|
* The accumulated contributions across an `addons[]` list, one array per
|
|
@@ -46,12 +51,25 @@ export type AddonEntry = string | {
|
|
|
46
51
|
*/
|
|
47
52
|
export interface DiscoveredContributions {
|
|
48
53
|
commands: CommandDescriptor[];
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
/** Opaque: `RemotePlugin[]` on the conductor surface. */
|
|
55
|
+
remotes: unknown[];
|
|
56
|
+
/** Opaque: `ExecutorPlugin[]` on the conductor surface. */
|
|
57
|
+
executors: unknown[];
|
|
58
|
+
/** Opaque: `WorkspacePlugin[]` on the conductor surface. */
|
|
59
|
+
workspaces: unknown[];
|
|
60
|
+
/** Opaque: `AgentCandidate[]` on the conductor surface. */
|
|
61
|
+
agents: unknown[];
|
|
53
62
|
connectionPlugins: DropSHPlugin[];
|
|
54
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* An OPAQUE per-surface accumulator. The kernel threads it without knowing its
|
|
66
|
+
* element type; the surface owner declares the concrete signature (see
|
|
67
|
+
* `@gaia-ai/conductor`'s `Preset`). `never[]` on the input side is deliberate:
|
|
68
|
+
* it keeps a concretely-typed accumulator such as
|
|
69
|
+
* `(acc: RemotePlugin[], opts) => RemotePlugin[]` structurally assignable to
|
|
70
|
+
* this opaque form, so a conductor-surface `Preset` still satisfies `GaiaPreset`.
|
|
71
|
+
*/
|
|
72
|
+
export type OpaqueAccumulator<O> = (acc: never[], opts: O) => unknown[] | Promise<unknown[]>;
|
|
55
73
|
/** The extension points each surface runs (the preset function names to call). */
|
|
56
74
|
export declare const SURFACE_KEYS: Record<GaiaSurface, Array<keyof DiscoveredContributions>>;
|
|
57
75
|
/**
|
|
@@ -64,10 +82,10 @@ export interface GaiaPreset<O = unknown> {
|
|
|
64
82
|
/** Meta-addon composition: children apply depth-first BEFORE this preset. */
|
|
65
83
|
addons?: AddonEntry[];
|
|
66
84
|
commands?: (acc: CommandDescriptor[], opts: O) => CommandDescriptor[] | Promise<CommandDescriptor[]>;
|
|
67
|
-
remotes?:
|
|
68
|
-
executors?:
|
|
69
|
-
workspaces?:
|
|
70
|
-
agents?:
|
|
85
|
+
remotes?: OpaqueAccumulator<O>;
|
|
86
|
+
executors?: OpaqueAccumulator<O>;
|
|
87
|
+
workspaces?: OpaqueAccumulator<O>;
|
|
88
|
+
agents?: OpaqueAccumulator<O>;
|
|
71
89
|
connectionPlugins?: (acc: DropSHPlugin[], opts: O) => DropSHPlugin[] | Promise<DropSHPlugin[]>;
|
|
72
90
|
}
|
|
73
91
|
/** The preset function keys, for shape-detection during discovery. */
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
// Settings (machine_id / project / states / hooks / scheduler) are NEVER
|
|
15
15
|
// preset-contributed — identity must not be composable — so this interface has
|
|
16
16
|
// no such members and an unknown preset export is rejected loudly at discovery.
|
|
17
|
+
//
|
|
18
|
+
// GAIA-224 (Finding 6, decision 7): this module is surface-AGNOSTIC. It knows
|
|
19
|
+
// the accumulator NAMES of every surface (`SURFACE_KEYS`) and the shape of the
|
|
20
|
+
// pure-data command surface (`CommandDescriptor`), but the element types of the
|
|
21
|
+
// CONDUCTOR surface (`RemotePlugin` / `ExecutorPlugin` / `WorkspacePlugin` /
|
|
22
|
+
// `AgentCandidate`, and the `Ticket` an agent priority scores) live in
|
|
23
|
+
// `@gaia-ai/conductor`. Importing them here would give the kernel an
|
|
24
|
+
// `@gaia-ai/*` edge, which the acyclic guard forbids — so those four
|
|
25
|
+
// accumulators are OPAQUE (see `OpaqueAccumulator`) and the concrete view is
|
|
26
|
+
// declared by the surface owner (`@gaia-ai/conductor`'s `Preset`).
|
|
17
27
|
/** The extension points each surface runs (the preset function names to call). */
|
|
18
28
|
export const SURFACE_KEYS = {
|
|
19
29
|
command: ['commands'],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaia-ai/core",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "GAIA
|
|
3
|
+
"version": "0.6.1",
|
|
4
|
+
"description": "GAIA surface-agnostic kernel: host contract, split-config helpers, addon preset/discovery machinery, shared primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./dist/src/index.js",
|
|
12
|
-
"./plugins": "./dist/src/plugins-index.js",
|
|
13
|
-
"./builtins": "./dist/src/plugins/builtins-preset.js",
|
|
14
12
|
"./conductor-registry": "./dist/src/conductor-registry/index.js",
|
|
15
13
|
"./package.json": "./package.json"
|
|
16
14
|
},
|
|
@@ -26,9 +24,10 @@
|
|
|
26
24
|
"repository": {
|
|
27
25
|
"type": "git",
|
|
28
26
|
"url": "git+https://git.key-tec.de/keytec/gaia.git",
|
|
29
|
-
"directory": "
|
|
27
|
+
"directory": "gaia-cli/core"
|
|
30
28
|
},
|
|
31
29
|
"dependencies": {
|
|
30
|
+
"@dropsh/plugin-markdown": "^0.5.8",
|
|
32
31
|
"@dropsh/plugin-oauth2": "^0.5.7",
|
|
33
32
|
"commander": "^12.1.0",
|
|
34
33
|
"dropsh": "^0.5.8",
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-agent effort footprint parsed from that agent's run transcript
|
|
3
|
-
* (GAIA-132). The metrics are transcript-derived and therefore
|
|
4
|
-
* **agent-specific** (each agent's transcript has its own format), so parsing
|
|
5
|
-
* lives behind the agent abstraction (see {@link GaiaAgent.parseFootprint}) —
|
|
6
|
-
* the conductor stays agent-agnostic and writes the footprint verbatim.
|
|
7
|
-
* `duration_s` is likewise derived from the transcript (its first→last entry
|
|
8
|
-
* timestamps), NOT recomputed by the conductor from a re-read `started_at`
|
|
9
|
-
* (GAIA-151): the log is the single source of the run's wall-clock length, so
|
|
10
|
-
* there is no timestamp round-trip through JSON:API to mis-parse.
|
|
11
|
-
*/
|
|
12
|
-
export interface AgentFootprint {
|
|
13
|
-
/** Total tokens across every usage bucket of every assistant turn. */
|
|
14
|
-
tokens: number;
|
|
15
|
-
/**
|
|
16
|
-
* Wall-clock run length in seconds, derived from the transcript's first→last
|
|
17
|
-
* entry timestamps (GAIA-151). 0 when the transcript has fewer than two
|
|
18
|
-
* timestamped entries (empty/absent log).
|
|
19
|
-
*/
|
|
20
|
-
duration_s: number;
|
|
21
|
-
/** Number of assistant turns in the transcript. */
|
|
22
|
-
agent_turns: number;
|
|
23
|
-
/** Number of tool-use calls across all assistant turns. */
|
|
24
|
-
tool_calls: number;
|
|
25
|
-
/** Number of user-submitted prompts. */
|
|
26
|
-
user_prompts: number;
|
|
27
|
-
/** Total words across those user prompts. */
|
|
28
|
-
user_prompt_words: number;
|
|
29
|
-
/** Model of the last assistant turn, when present (informational). */
|
|
30
|
-
model?: string;
|
|
31
|
-
}
|
|
32
|
-
/** An all-zero footprint — the honest result for an empty/absent transcript. */
|
|
33
|
-
export declare function emptyAgentFootprint(): AgentFootprint;
|
|
34
|
-
/**
|
|
35
|
-
* A GAIA agent: the program the conductor runs to work a ticket (e.g. claude).
|
|
36
|
-
* It knows how it is launched (CLI + model + flags) and where its per-run
|
|
37
|
-
* transcript/log lives — so the conductor stays agent-agnostic and the CLI can
|
|
38
|
-
* attach the run log on release without agent-specific knowledge.
|
|
39
|
-
*/
|
|
40
|
-
export interface GaiaAgent {
|
|
41
|
-
/** Stable id, e.g. 'claude'. */
|
|
42
|
-
readonly id: string;
|
|
43
|
-
/**
|
|
44
|
-
* Build the full agent CLI invocation for a GAIA prompt. With an empty
|
|
45
|
-
* prompt, returns the bare launch command (no prompt argument).
|
|
46
|
-
*/
|
|
47
|
-
launchCommand(prompt: string): string;
|
|
48
|
-
/**
|
|
49
|
-
* Locate and read this agent's run transcript for a run that executed in
|
|
50
|
-
* `worktreePath`. MUST return '' (never throw) when nothing is found.
|
|
51
|
-
*/
|
|
52
|
-
getRunLog(worktreePath: string): Promise<string>;
|
|
53
|
-
/**
|
|
54
|
-
* Parse this agent's run transcript (as returned by {@link getRunLog}) into
|
|
55
|
-
* a footprint of effort metrics (GAIA-132). The transcript format is
|
|
56
|
-
* agent-specific, so each agent owns its own parser. MUST be tolerant of
|
|
57
|
-
* blank/partial/absent input (never throw) — an empty log yields
|
|
58
|
-
* {@link emptyAgentFootprint}.
|
|
59
|
-
*/
|
|
60
|
-
parseFootprint(log: string): AgentFootprint;
|
|
61
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static HTTP Basic auth provider built from an inline base64 `user:pass` token
|
|
3
|
-
* (conductor.config.local.js `auth.basic`, or the GAIA_E2E_BASIC env for tests).
|
|
4
|
-
* Returns the `{ id, authProvider }` plugin shape that dropsh's resolveAuth reads
|
|
5
|
-
* from `config.plugins`. Replaces the per-file basicAuthProvider that used to be
|
|
6
|
-
* hand-written into each dropsh.config.js.
|
|
7
|
-
*/
|
|
8
|
-
export declare function basicAuthProvider(tokenBase64: string): {
|
|
9
|
-
kind: 'auth';
|
|
10
|
-
id: string;
|
|
11
|
-
authProvider: unknown;
|
|
12
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Static HTTP Basic auth provider built from an inline base64 `user:pass` token
|
|
3
|
-
* (conductor.config.local.js `auth.basic`, or the GAIA_E2E_BASIC env for tests).
|
|
4
|
-
* Returns the `{ id, authProvider }` plugin shape that dropsh's resolveAuth reads
|
|
5
|
-
* from `config.plugins`. Replaces the per-file basicAuthProvider that used to be
|
|
6
|
-
* hand-written into each dropsh.config.js.
|
|
7
|
-
*/
|
|
8
|
-
export function basicAuthProvider(tokenBase64) {
|
|
9
|
-
const authProvider = {
|
|
10
|
-
id: 'basic_auth',
|
|
11
|
-
displayName: 'HTTP Basic (inline)',
|
|
12
|
-
capabilities: { login: false, logout: false, status: true },
|
|
13
|
-
async login() {
|
|
14
|
-
throw new Error('GAIA uses static inline HTTP Basic auth.');
|
|
15
|
-
},
|
|
16
|
-
async logout() { },
|
|
17
|
-
async status() {
|
|
18
|
-
return { loggedIn: true, provider: 'basic_auth' };
|
|
19
|
-
},
|
|
20
|
-
createAdapter() {
|
|
21
|
-
return {
|
|
22
|
-
async apply(req) {
|
|
23
|
-
return {
|
|
24
|
-
...req,
|
|
25
|
-
headers: {
|
|
26
|
-
...(req.headers ?? {}),
|
|
27
|
-
Authorization: `Basic ${tokenBase64}`,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
// GAIA-215: `.kind='auth'` makes the plugin tag total (every GAIA plugin
|
|
35
|
-
// self-identifies); dropsh ignores the extra field and reads `authProvider`.
|
|
36
|
-
return { kind: 'auth', id: 'gaia-basic-auth', authProvider };
|
|
37
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { GaiaPreset } from './preset.js';
|
|
2
|
-
/** Conductor surface: the Drupal control-plane remote (the sole shipped remote). */
|
|
3
|
-
export declare const remotes: GaiaPreset['remotes'];
|
|
4
|
-
/** Connection surface: inline HTTP Basic auth, only when a `basic` token is set. */
|
|
5
|
-
export declare const connectionPlugins: GaiaPreset['connectionPlugins'];
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// GAIA-215: the core built-ins preset, exposed as `@gaia-ai/core/builtins`. It
|
|
2
|
-
// self-declares GAIA's shipped default contributions the way any addon does —
|
|
3
|
-
// retiring the `@gaia-ai/core/plugins` barrel `export:` warts (`drupalRemote`,
|
|
4
|
-
// `basicAuthProvider`). List it in `conductor.config.js` addons to auto-wire the
|
|
5
|
-
// Drupal control-plane remote; list it in `gaia.config.js` addons with a
|
|
6
|
-
// `{ basic: '<base64>' }` option for inline HTTP Basic auth. The barrel stays
|
|
7
|
-
// for back-compat (the descriptor `export:` path); new configs name this preset.
|
|
8
|
-
//
|
|
9
|
-
// It deliberately does NOT contribute a workspace: every executor addon ships
|
|
10
|
-
// its own paired workspace (herdr → herdrWorkspace, fake → fakeWorkspace), so a
|
|
11
|
-
// builtin `gitWorkspace` would only fight the executor's workspace on the
|
|
12
|
-
// canonical config (a guaranteed last-wins warning). A git-only setup can still
|
|
13
|
-
// name `gitWorkspace` explicitly via the `@gaia-ai/core/plugins` barrel.
|
|
14
|
-
//
|
|
15
|
-
// It is deliberately light + dependency-free at the top level (factory calls
|
|
16
|
-
// only), so the host can import it at boot without pulling the remote runtime.
|
|
17
|
-
import { basicAuthProvider } from './auth/basic.js';
|
|
18
|
-
import { drupalRemote } from './remote/drupal.js';
|
|
19
|
-
/** Conductor surface: the Drupal control-plane remote (the sole shipped remote). */
|
|
20
|
-
export const remotes = (acc) => [...acc, drupalRemote()];
|
|
21
|
-
/** Connection surface: inline HTTP Basic auth, only when a `basic` token is set. */
|
|
22
|
-
export const connectionPlugins = (acc, opts) => {
|
|
23
|
-
const o = (opts ?? {});
|
|
24
|
-
if (typeof o.basic !== 'string' || o.basic.trim() === '')
|
|
25
|
-
return acc;
|
|
26
|
-
// basicAuthProvider returns the dropsh auth-plugin shape ({ id, authProvider })
|
|
27
|
-
// minus `requiredModules` (dropsh tolerates its absence for auth-only plugins).
|
|
28
|
-
return [
|
|
29
|
-
...acc,
|
|
30
|
-
basicAuthProvider(o.basic),
|
|
31
|
-
];
|
|
32
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
export interface SpawnedSession {
|
|
2
|
-
sessionRef: string;
|
|
3
|
-
}
|
|
4
|
-
export interface ExecutorCapabilities {
|
|
5
|
-
persistent: boolean;
|
|
6
|
-
}
|
|
7
|
-
export interface SpawnRunInput {
|
|
8
|
-
ticket: {
|
|
9
|
-
uuid: string;
|
|
10
|
-
identifier: string;
|
|
11
|
-
title: string;
|
|
12
|
-
branchName: string;
|
|
13
|
-
state: string;
|
|
14
|
-
url?: string;
|
|
15
|
-
};
|
|
16
|
-
run: {
|
|
17
|
-
uuid: string;
|
|
18
|
-
id: number;
|
|
19
|
-
handler: string;
|
|
20
|
-
};
|
|
21
|
-
workspacePath: string;
|
|
22
|
-
instructions: {
|
|
23
|
-
path: string;
|
|
24
|
-
sha256: string;
|
|
25
|
-
text: string;
|
|
26
|
-
} | null;
|
|
27
|
-
command?: string;
|
|
28
|
-
env?: Record<string, string>;
|
|
29
|
-
}
|
|
30
|
-
/** The four lifecycle-hook slots, keyed exactly like `config.hooks`. */
|
|
31
|
-
export type HookName = 'after_create' | 'before_run' | 'after_run' | 'after_done';
|
|
32
|
-
/** Context for a hook invocation — carries the ticket for observable logging. */
|
|
33
|
-
export interface HookContext {
|
|
34
|
-
/** The ticket identifier/uuid the hook is running for (log context). */
|
|
35
|
-
ticket: string;
|
|
36
|
-
}
|
|
37
|
-
export interface GaiaExecutor {
|
|
38
|
-
id: string;
|
|
39
|
-
capabilities(): ExecutorCapabilities;
|
|
40
|
-
/**
|
|
41
|
-
* Run the lifecycle hook `name` (command from `config.hooks[name]`) in `cwd`,
|
|
42
|
-
* best-effort. This is the SINGLE catch point for all lifecycle hooks:
|
|
43
|
-
*
|
|
44
|
-
* - MUST NEVER throw. No configured command → silent no-op. A failing command
|
|
45
|
-
* → `logger.error({hook,worktree,ticket,err}, 'lifecycle hook failed')` then
|
|
46
|
-
* return. So a hook failure never aborts dispatch or wedges a run in
|
|
47
|
-
* `claimed`.
|
|
48
|
-
* - The underlying shell command still fails honestly (a non-zero exit
|
|
49
|
-
* rejects); only the executor catches + logs + continues.
|
|
50
|
-
*
|
|
51
|
-
* `env`, when given, is the run's resolved environment (per-ticket env_vars
|
|
52
|
-
* merged with the core GAIA_* vars, GAIA-99), merged over the hook process's
|
|
53
|
-
* inherited env. Values may be sensitive — implementations must never log
|
|
54
|
-
* them (log key names only).
|
|
55
|
-
*/
|
|
56
|
-
runHook(name: HookName, cwd: string, ctx: HookContext, env?: Record<string, string>): Promise<void>;
|
|
57
|
-
startRun(input: SpawnRunInput): Promise<SpawnedSession>;
|
|
58
|
-
/**
|
|
59
|
-
* Signal the run's agent to stop. Called by the conductor's run-finalise pass
|
|
60
|
-
* BEFORE it captures the agent transcript (GAIA-132), so a stop must not
|
|
61
|
-
* destroy the log. For herdr this is a NO-OP: at finalise time the agent is
|
|
62
|
-
* idle and its jsonl transcript is already fully written to disk, and the
|
|
63
|
-
* subsequent {@link cleanupRun} tab-close kills the PTY (the agent dies with
|
|
64
|
-
* it). The seam exists for executors whose agent outlives its UI surface.
|
|
65
|
-
* Best-effort; gated by the conductor on `capabilities().persistent`.
|
|
66
|
-
*/
|
|
67
|
-
stopRun(branch: string): Promise<void>;
|
|
68
|
-
/**
|
|
69
|
-
* Tear down ONE run's hosted UI surface — for herdr, close only the tab whose
|
|
70
|
-
* label carries the `#<runId>` token (`startRun` labels every tab
|
|
71
|
-
* `<identifier> · <state> #<run.id>`), via `herdr tab close <tab_id>` (killing
|
|
72
|
-
* that PTY). Run-scoped by design (GAIA-183): a sibling run's tab in the same
|
|
73
|
-
* branch workspace — a still-open prior-state run or a concurrent re-claim —
|
|
74
|
-
* and any non-run tab are left untouched. Called as the LAST finalisation step,
|
|
75
|
-
* strictly after the transcript is captured, and again at dispatch to clear a
|
|
76
|
-
* reused workspace's leftover tab for the run being (re-)started. No matching
|
|
77
|
-
* tab → a quiet no-op. Does NOT touch the branch worktree (that is the
|
|
78
|
-
* reap/{@link removeWorktree} lifecycle). Best-effort: a failing tab-close is
|
|
79
|
-
* swallowed and never aborts finalisation or dispatch. A no-op for
|
|
80
|
-
* non-persistent executors.
|
|
81
|
-
*/
|
|
82
|
-
cleanupRun(branch: string, runId: number): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* Tear down the branch's entire worktree (git worktree + hosted workspace),
|
|
85
|
-
* reclaiming its disk. Called by the conductor's ticket-cleanup pass once a
|
|
86
|
-
* ticket is done. A no-op for non-persistent executors (no hosted workspace);
|
|
87
|
-
* the conductor gates the call on `capabilities().persistent`.
|
|
88
|
-
*
|
|
89
|
-
* `worktreePath` is the stable, identifier-derived worktree path (from the
|
|
90
|
-
* ticket's latest run). Prefer it over `branch` to resolve the worktree: the
|
|
91
|
-
* checked-out branch is mutable (the coding agent may rename/switch it), the
|
|
92
|
-
* path is not.
|
|
93
|
-
*
|
|
94
|
-
* Returns whether the worktree was actually present on THIS host and torn
|
|
95
|
-
* down (or reclaimed on disk) — i.e. whether the teardown happened locally.
|
|
96
|
-
* `false` means nothing matched here: the worktree is either already gone or
|
|
97
|
-
* lives on another conductor's host. The reaper uses this to avoid marking a
|
|
98
|
-
* ticket `cleaned_up` for a worktree it did not actually tear down (a
|
|
99
|
-
* cross-host false-teardown), leaving it for the host that physically holds
|
|
100
|
-
* it. A genuine failure still throws (surfaced as a teardown miss); a `false`
|
|
101
|
-
* return is a clean "not here", not an error.
|
|
102
|
-
*/
|
|
103
|
-
removeWorktree(branch: string, worktreePath?: string): Promise<boolean>;
|
|
104
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { DropSHPlugin } from 'dropsh/plugin';
|
|
2
|
-
import type { ConductorLogger } from '../core/logger.js';
|
|
3
|
-
import type { ConductorFileConfig } from '../types.js';
|
|
4
|
-
import type { GaiaAgent } from './agent/agent.js';
|
|
5
|
-
import type { GaiaExecutor } from './executor/executor.js';
|
|
6
|
-
import type { GaiaRemote, Ticket } from './remote/remote.js';
|
|
7
|
-
import type { GaiaWorkspace } from './workspace/workspace.js';
|
|
8
|
-
/** Runtime dependencies handed to a plugin factory at selection time. */
|
|
9
|
-
export interface ExecutorDeps {
|
|
10
|
-
/** The in-scope conductor logger — the executor logs hook failures through it. */
|
|
11
|
-
logger: ConductorLogger;
|
|
12
|
-
}
|
|
13
|
-
export interface RemotePlugin extends DropSHPlugin {
|
|
14
|
-
readonly kind: 'remote';
|
|
15
|
-
readonly id: string;
|
|
16
|
-
readonly requiredModules: string[];
|
|
17
|
-
createRemote(config: ConductorFileConfig): Promise<GaiaRemote>;
|
|
18
|
-
}
|
|
19
|
-
export interface ExecutorPlugin extends DropSHPlugin {
|
|
20
|
-
readonly kind: 'executor';
|
|
21
|
-
readonly id: string;
|
|
22
|
-
readonly requiredModules: string[];
|
|
23
|
-
createExecutor(config: ConductorFileConfig, deps: ExecutorDeps): Promise<GaiaExecutor>;
|
|
24
|
-
}
|
|
25
|
-
export interface WorkspacePlugin extends DropSHPlugin {
|
|
26
|
-
readonly kind: 'workspace';
|
|
27
|
-
readonly id: string;
|
|
28
|
-
readonly requiredModules: string[];
|
|
29
|
-
createWorkspace(config: ConductorFileConfig): Promise<GaiaWorkspace>;
|
|
30
|
-
}
|
|
31
|
-
export interface AgentPlugin extends DropSHPlugin {
|
|
32
|
-
readonly kind: 'agent';
|
|
33
|
-
readonly id: string;
|
|
34
|
-
readonly requiredModules: string[];
|
|
35
|
-
createAgent(config: ConductorFileConfig): Promise<GaiaAgent>;
|
|
36
|
-
}
|
|
37
|
-
/** Resolves the remote from its named config slot. */
|
|
38
|
-
export declare function selectRemote(config: ConductorFileConfig): Promise<GaiaRemote>;
|
|
39
|
-
/** Resolves the executor from its named config slot, injecting the logger. */
|
|
40
|
-
export declare function selectExecutor(config: ConductorFileConfig, logger: ConductorLogger): Promise<GaiaExecutor>;
|
|
41
|
-
/** Resolves the workspace from its named config slot. */
|
|
42
|
-
export declare function selectWorkspace(config: ConductorFileConfig): Promise<GaiaWorkspace>;
|
|
43
|
-
/** A config-side agent choice: an agent plugin + an optional static priority over the ticket. */
|
|
44
|
-
export interface AgentCandidate {
|
|
45
|
-
agent: AgentPlugin;
|
|
46
|
-
priority?: (ticket: Ticket) => number;
|
|
47
|
-
}
|
|
48
|
-
/** A constructed candidate: the agent id, its GaiaAgent, and the config-side priority. */
|
|
49
|
-
export interface ResolvedAgent {
|
|
50
|
-
id: string;
|
|
51
|
-
agent: GaiaAgent;
|
|
52
|
-
priority?: (ticket: Ticket) => number;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Pick the agent for a ticket: highest `priority(ticket)` wins; a candidate with
|
|
56
|
-
* no `priority` scores lowest; ties resolve by config array order (stable sort).
|
|
57
|
-
*/
|
|
58
|
-
export declare function selectAgent(candidates: ResolvedAgent[], ticket: Ticket): ResolvedAgent;
|
|
59
|
-
/** Constructs every agent candidate from the resolved config slot (single or array). */
|
|
60
|
-
export declare function selectAgents(config: ConductorFileConfig): Promise<ResolvedAgent[]>;
|