@gaia-ai/conductor 0.4.1 → 0.4.3
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/dist/src/cli/gaia.js +30 -2
- package/dist/src/config.d.ts +21 -4
- package/dist/src/config.js +29 -10
- package/dist/src/core/conductor.js +1 -23
- package/package.json +3 -3
package/dist/src/cli/gaia.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { dirname } from 'node:path';
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
3
|
import { createInterface } from 'node:readline';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
4
5
|
import { CommandRunner, conductorId, createLogger, exec, setDefaultCommandRunner, } from '@gaia-ai/core';
|
|
5
6
|
import { selectAgent, selectExecutor, selectRemote, selectWorkspace, } from '@gaia-ai/core/plugins';
|
|
6
7
|
import { Command } from 'commander';
|
|
@@ -368,9 +369,36 @@ async function promptSecret() {
|
|
|
368
369
|
}
|
|
369
370
|
}
|
|
370
371
|
// --- program ----------------------------------------------------------------
|
|
372
|
+
// Report the CLI's own package version. Walks up from this module to the
|
|
373
|
+
// nearest @gaia-ai/conductor package.json so it resolves both from the
|
|
374
|
+
// compiled dist/src/cli/gaia.js (3 dirs up) and the src/cli/gaia.ts vitest
|
|
375
|
+
// runs (2 dirs up). Same release tag across packages ⇒ == @gaia-ai/gaia.
|
|
376
|
+
function resolveCliVersion() {
|
|
377
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
378
|
+
for (let i = 0; i < 6; i++) {
|
|
379
|
+
try {
|
|
380
|
+
const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
|
|
381
|
+
if (pkg.name === '@gaia-ai/conductor')
|
|
382
|
+
return pkg.version ?? '0.0.0';
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// no package.json here — keep walking up
|
|
386
|
+
}
|
|
387
|
+
dir = dirname(dir);
|
|
388
|
+
}
|
|
389
|
+
return '0.0.0';
|
|
390
|
+
}
|
|
371
391
|
function buildProgram(deps) {
|
|
372
392
|
const program = new Command();
|
|
373
393
|
program.name('gaia').description('GAIA conductor + client CLI');
|
|
394
|
+
const cliVersion = resolveCliVersion();
|
|
395
|
+
program.version(cliVersion); // -V, --version
|
|
396
|
+
program
|
|
397
|
+
.command('version')
|
|
398
|
+
.description('output the gaia CLI version')
|
|
399
|
+
.action(() => {
|
|
400
|
+
console.log(cliVersion);
|
|
401
|
+
});
|
|
374
402
|
const conductor = program
|
|
375
403
|
.command('conductor')
|
|
376
404
|
.description('node-agent lifecycle + local registry')
|
package/dist/src/config.d.ts
CHANGED
|
@@ -4,10 +4,27 @@ import { type ConductorFileConfig } from '@gaia-ai/core';
|
|
|
4
4
|
* the agent must stop instead of running the whole flow in one session. The run
|
|
5
5
|
* is closed automatically when the ticket state changes on the next claim - the
|
|
6
6
|
* agent does not release it. Run mechanics live here (not in the repo's
|
|
7
|
-
* WORKFLOW.md).
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* WORKFLOW.md). The prompt routes through the gaia skill (`ticket:run`) rather
|
|
8
|
+
* than pointing at WORKFLOW.md directly (GAIA-125): the intake splash + state
|
|
9
|
+
* engine are a skill mechanic, so a bare "follow WORKFLOW.md" pointer left the
|
|
10
|
+
* splash unrendered unless an external skill-forcing hook happened to fire. A
|
|
11
|
+
* conductor config may override via the `prompt` field.
|
|
12
|
+
*
|
|
13
|
+
* The ticket + its comments are NOT embedded (GAIA-112): embedding unbounded
|
|
14
|
+
* ticket content into a single typed pane line overran the PTY canonical line
|
|
15
|
+
* cap (MAX_CANON = 4096 B) and truncated the dispatch command. Instead the
|
|
16
|
+
* prompt is a bounded, constant-size pointer and the agent reads the ticket +
|
|
17
|
+
* all comments at run start via `gaia dropsh read … --include comments`.
|
|
18
|
+
*
|
|
19
|
+
* The prompt is a SINGLE LINE — no newlines, no control chars (GAIA-128). herdr
|
|
20
|
+
* types it into the pane as one line, so a newline would submit early and any
|
|
21
|
+
* control char would force bash-only `$'…'` quoting that fish can't parse.
|
|
22
|
+
* Being single-line + bounded, plain `'…'` shell-quoting suffices (fish-safe)
|
|
23
|
+
* and the typed line stays well under the 4096 B cap — so NO base64/`bash -c`
|
|
24
|
+
* wrapper and NO multiline handling are needed (that wrapper, GAIA-118, was the
|
|
25
|
+
* thing that re-inflated the line past the cap and truncated it mid-quote).
|
|
26
|
+
* Placeholders: `{identifier}`, `{state}`, `{runUuid}` ({state} falls back to
|
|
27
|
+
* `triage` for unclassified tickets).
|
|
11
28
|
*/
|
|
12
29
|
export declare const DEFAULT_AGENT_PROMPT: string;
|
|
13
30
|
/**
|
package/dist/src/config.js
CHANGED
|
@@ -8,23 +8,42 @@ import { conductorId, } from '@gaia-ai/core';
|
|
|
8
8
|
* the agent must stop instead of running the whole flow in one session. The run
|
|
9
9
|
* is closed automatically when the ticket state changes on the next claim - the
|
|
10
10
|
* agent does not release it. Run mechanics live here (not in the repo's
|
|
11
|
-
* WORKFLOW.md).
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* WORKFLOW.md). The prompt routes through the gaia skill (`ticket:run`) rather
|
|
12
|
+
* than pointing at WORKFLOW.md directly (GAIA-125): the intake splash + state
|
|
13
|
+
* engine are a skill mechanic, so a bare "follow WORKFLOW.md" pointer left the
|
|
14
|
+
* splash unrendered unless an external skill-forcing hook happened to fire. A
|
|
15
|
+
* conductor config may override via the `prompt` field.
|
|
16
|
+
*
|
|
17
|
+
* The ticket + its comments are NOT embedded (GAIA-112): embedding unbounded
|
|
18
|
+
* ticket content into a single typed pane line overran the PTY canonical line
|
|
19
|
+
* cap (MAX_CANON = 4096 B) and truncated the dispatch command. Instead the
|
|
20
|
+
* prompt is a bounded, constant-size pointer and the agent reads the ticket +
|
|
21
|
+
* all comments at run start via `gaia dropsh read … --include comments`.
|
|
22
|
+
*
|
|
23
|
+
* The prompt is a SINGLE LINE — no newlines, no control chars (GAIA-128). herdr
|
|
24
|
+
* types it into the pane as one line, so a newline would submit early and any
|
|
25
|
+
* control char would force bash-only `$'…'` quoting that fish can't parse.
|
|
26
|
+
* Being single-line + bounded, plain `'…'` shell-quoting suffices (fish-safe)
|
|
27
|
+
* and the typed line stays well under the 4096 B cap — so NO base64/`bash -c`
|
|
28
|
+
* wrapper and NO multiline handling are needed (that wrapper, GAIA-118, was the
|
|
29
|
+
* thing that re-inflated the line past the cap and truncated it mid-quote).
|
|
30
|
+
* Placeholders: `{identifier}`, `{state}`, `{runUuid}` ({state} falls back to
|
|
31
|
+
* `triage` for unclassified tickets).
|
|
15
32
|
*/
|
|
16
33
|
export const DEFAULT_AGENT_PROMPT = `You are a GAIA agent working ticket {identifier}, current state: {state}. ` +
|
|
17
|
-
`
|
|
34
|
+
`Invoke the gaia skill and run \`ticket:run {identifier} {state}\` — it renders ` +
|
|
35
|
+
`the intake splash, runs the {state} engine, and applies WORKFLOW.md's {state} policy. ` +
|
|
18
36
|
`This run covers EXACTLY the {state} state - do only its work. Do not start, ` +
|
|
19
37
|
`prepare, or perform any later state's work, even if WORKFLOW.md mentions ` +
|
|
20
38
|
`transitioning onward. When the {state} work is done and you have no open ` +
|
|
21
39
|
`questions, STOP - do not pick up or work any further state or ticket. If ` +
|
|
22
40
|
`blocked or you need a human, stop and surface the blocker. After you have ` +
|
|
23
|
-
`written the ticket's next state, run /exit to end this session
|
|
24
|
-
`
|
|
25
|
-
`
|
|
26
|
-
`
|
|
27
|
-
|
|
41
|
+
`written the ticket's next state, run /exit to end this session. ` +
|
|
42
|
+
`First, read the ticket + all comments in one call: run ` +
|
|
43
|
+
`gaia dropsh read gaia_ticket/gaia_ticket/$GAIA_ID --include comments — the ` +
|
|
44
|
+
`latest \`summary\` comment is review feedback you MUST address; any ` +
|
|
45
|
+
`\`spec\`/\`diagnose\` comment is the agreed plan. Treat them as in-scope ` +
|
|
46
|
+
`acceptance criteria.`;
|
|
28
47
|
function requirePlugin(value, kind) {
|
|
29
48
|
if (!isRecord(value) || value.kind !== kind) {
|
|
30
49
|
throw new Error(`conductor config requires a ${kind} plugin in the "${kind}" slot`);
|
|
@@ -16,26 +16,6 @@ function sleep(ms, signal) {
|
|
|
16
16
|
signal?.addEventListener('abort', onAbort, { once: true });
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Formats a ticket's comments into the `{comments}` prompt block, oldest first.
|
|
21
|
-
* The conductor injects this so a review→coding bounce reaches the coder with the
|
|
22
|
-
* review summary in hand, independent of whether the agent remembers to fetch it.
|
|
23
|
-
*
|
|
24
|
-
* The body is the raw gaia_rich markup — the agent reads HTML fine, so we don't
|
|
25
|
-
* strip it (a tag/entity stripper is a maintenance footgun that buys nothing for
|
|
26
|
-
* an LLM reader).
|
|
27
|
-
*/
|
|
28
|
-
function renderComments(comments) {
|
|
29
|
-
if (comments.length === 0) {
|
|
30
|
-
return '(no comments on this ticket yet)';
|
|
31
|
-
}
|
|
32
|
-
return comments
|
|
33
|
-
.map((c, i) => {
|
|
34
|
-
const when = c.created ? ` (${c.created})` : '';
|
|
35
|
-
return `[#${i + 1}] type=${c.type}${when}\n${c.body}`;
|
|
36
|
-
})
|
|
37
|
-
.join('\n\n---\n\n');
|
|
38
|
-
}
|
|
39
19
|
/**
|
|
40
20
|
* A run-env key is reserved when it names a conductor-provided core variable:
|
|
41
21
|
* any `GAIA_*`, `WORKSPACE_ROOT`, or `TICKET_URL`. User `env_vars` may not
|
|
@@ -99,8 +79,7 @@ function renderPrompt(template, values) {
|
|
|
99
79
|
return template
|
|
100
80
|
.replaceAll('{identifier}', values.identifier)
|
|
101
81
|
.replaceAll('{state}', values.state)
|
|
102
|
-
.replaceAll('{runUuid}', values.runUuid)
|
|
103
|
-
.replaceAll('{comments}', renderComments(values.comments));
|
|
82
|
+
.replaceAll('{runUuid}', values.runUuid);
|
|
104
83
|
}
|
|
105
84
|
export class Conductor {
|
|
106
85
|
config;
|
|
@@ -358,7 +337,6 @@ export class Conductor {
|
|
|
358
337
|
identifier: t.identifier,
|
|
359
338
|
state: t.state || 'triage',
|
|
360
339
|
runUuid: run.runUuid,
|
|
361
|
-
comments: t.comments,
|
|
362
340
|
})
|
|
363
341
|
: '';
|
|
364
342
|
await this.executor.startRun({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaia-ai/conductor",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "GAIA conductor engine + CLI: registers, claims tickets via JSON:API, dispatches agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"directory": "conductor/packages/conductor"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@gaia-ai/core": "^0.4.
|
|
28
|
+
"@gaia-ai/core": "^0.4.3",
|
|
29
29
|
"@dropsh/plugin-oauth2": "^0.4.1",
|
|
30
30
|
"@dropsh/plugin-jsonapi-schema": "^0.5.1",
|
|
31
31
|
"commander": "^12.1.0",
|
|
32
|
-
"dropsh": "^0.5.
|
|
32
|
+
"dropsh": "^0.5.3"
|
|
33
33
|
}
|
|
34
34
|
}
|