agentic-orchestrator 0.1.1 → 0.1.2

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 CHANGED
@@ -231,8 +231,8 @@ Behavior:
231
231
  - `feature_id` is derived from file stem (strips `.spec` or `-spec` suffixes when present).
232
232
  - each ingested feature runs `feature.init`, then state source metadata is patched with source path/hash.
233
233
  - Provider selection precedence:
234
- 1. CLI flags (`--agent-provider`, `--agent-model`, `--provider-config-env`)
235
- 2. env vars (`AOP_AGENT_PROVIDER`, `AOP_AGENT_MODEL`, `AOP_PROVIDER_CONFIG_ENV`)
234
+ 1. CLI flags (`--agent-provider`, `--agent-model`, `--agent-config`, `--provider-config-env`)
235
+ 2. env vars (`AOP_AGENT_PROVIDER`, `AOP_AGENT_MODEL`, `AOP_AGENT_CONFIG`/`AOP_AGENT_CONFIG_JSON`, `AOP_PROVIDER_CONFIG_ENV`)
236
236
  3. `agentic/orchestrator/agents.yaml` runtime defaults
237
237
  - Runtime start:
238
238
  - starts `SupervisorRuntime` with `max_active_features=5`, `max_parallel_gate_runs=3`.
@@ -355,8 +355,9 @@ Supported options:
355
355
  |-------------------------------------------------------|-----------------------------------------------------------------------------------|
356
356
  | `-fi <path>` | Run exactly one spec file |
357
357
  | `-fl <path>` | Resolve all `**/*.md` files recursively in a folder (deterministic lexical order) |
358
- | `--agent-provider <codex\\|claude\\|gemini\\|custom>` | Provider selection |
358
+ | `--agent-provider <codex\\|claude\\|gemini\\|custom\\|kiro-cli\\|copilot>` | Provider selection |
359
359
  | `--agent-model <model-id>` | Model selection |
360
+ | `--agent-config <json-object>` | Additional provider-specific agent config (for example command/args payload) |
360
361
  | `--provider-config-env <ENV_VAR>` | Provider auth/config environment variable name |
361
362
  | `--transport <mcp\\|inprocess>` | Tool transport selection (default `mcp`) |
362
363
  | `--takeover-stale-run` | Allow stale run-lease takeover during `run` |
@@ -386,7 +387,7 @@ Feature ID derivation for non-canonical inputs:
386
387
  Provider resolution precedence:
387
388
 
388
389
  1. CLI flags
389
- 2. env vars (`AOP_AGENT_PROVIDER`, `AOP_AGENT_MODEL`, `AOP_PROVIDER_CONFIG_ENV`)
390
+ 2. env vars (`AOP_AGENT_PROVIDER`, `AOP_AGENT_MODEL`, `AOP_AGENT_CONFIG`/`AOP_AGENT_CONFIG_JSON`, `AOP_PROVIDER_CONFIG_ENV`)
390
391
  3. `agentic/orchestrator/agents.yaml` runtime defaults
391
392
 
392
393
  Transport behavior:
@@ -430,6 +431,7 @@ Coverage parser:
430
431
 
431
432
  - role-specific system prompt paths
432
433
  - default provider/model/config-env fallback values
434
+ - optional `runtime.provider_configs.<provider>` objects for provider-specific payloads (for example `kiro-cli chat --agent dev`)
433
435
  - stack-specific examples: [`example-configurations/node/`](example-configurations/node) and [`example-configurations/java/`](example-configurations/java)
434
436
 
435
437
  ### Example configuration bundles
@@ -11,4 +11,14 @@ runtime:
11
11
  default_provider: custom
12
12
  default_model: local-default
13
13
  provider_config_env: AOP_PROVIDER_CONFIG_ENV
14
+ provider_configs:
15
+ kiro-cli:
16
+ command: kiro-cli
17
+ args:
18
+ - chat
19
+ - --agent
20
+ - dev
21
+ copilot:
22
+ command: copilot
23
+ args: []
14
24
  role_provider_overrides: {}
@@ -25,10 +25,19 @@
25
25
  "properties": {
26
26
  "default_provider": {
27
27
  "type": "string",
28
- "enum": ["codex", "claude", "gemini", "custom"]
28
+ "enum": ["codex", "claude", "gemini", "custom", "kiro-cli", "copilot"]
29
29
  },
30
30
  "default_model": { "type": "string" },
31
+ "default_agent_config": {
32
+ "type": "object"
33
+ },
31
34
  "provider_config_env": { "type": "string" },
35
+ "provider_configs": {
36
+ "type": "object",
37
+ "additionalProperties": {
38
+ "type": "object"
39
+ }
40
+ },
32
41
  "role_provider_overrides": {
33
42
  "type": "object"
34
43
  }
@@ -79,6 +79,11 @@ export class CliArgumentParser {
79
79
  index += 1;
80
80
  continue;
81
81
  }
82
+ if (token === '--agent-config') {
83
+ options.agent_config = next;
84
+ index += 1;
85
+ continue;
86
+ }
82
87
  if (token === '--provider-config-env') {
83
88
  options.provider_config_env = next;
84
89
  index += 1;
@@ -9,6 +9,7 @@ export interface CliOptions {
9
9
  remove_branch?: string;
10
10
  agent_provider?: string;
11
11
  agent_model?: string;
12
+ agent_config?: string;
12
13
  provider_config_env?: string;
13
14
  transport?: string;
14
15
  takeover_stale_run?: boolean;
@@ -41,6 +41,8 @@ export interface AgentsRuntimeConfig {
41
41
  default_provider?: string;
42
42
  default_model?: string;
43
43
  provider_config_env?: string;
44
+ default_agent_config?: Record<string, unknown>;
45
+ provider_configs?: Record<string, Record<string, unknown>>;
44
46
  }
45
47
 
46
48
  export interface AgentsConfigSnapshot {
@@ -7,10 +7,11 @@ export interface AppError extends Error {
7
7
  }
8
8
 
9
9
  export interface ProviderSelection {
10
- provider: 'codex' | 'claude' | 'gemini' | 'custom';
10
+ provider: 'codex' | 'claude' | 'gemini' | 'custom' | 'kiro-cli' | 'copilot';
11
11
  model: string;
12
12
  provider_config_env: string | null;
13
13
  provider_config_ref: string | null;
14
+ agent_config?: Record<string, unknown> | null;
14
15
  }
15
16
 
16
17
  interface ResolveSelectionInput {
@@ -21,11 +22,78 @@ interface ResolveSelectionInput {
21
22
  default_provider?: string;
22
23
  default_model?: string;
23
24
  provider_config_env?: string;
25
+ default_agent_config?: unknown;
26
+ provider_configs?: Record<string, unknown>;
24
27
  };
25
28
  };
26
29
  }
27
30
 
28
- export const SUPPORTED_PROVIDERS = new Set<ProviderSelection['provider']>(['codex', 'claude', 'gemini', 'custom']);
31
+ type ResolveSelectionRuntimeConfig = NonNullable<ResolveSelectionInput['agentsConfig']>['runtime'];
32
+
33
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
34
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
35
+ }
36
+
37
+ function invalidAgentConfigError(details: Record<string, unknown>): AppError {
38
+ const error = new Error(ERROR_CODES.INVALID_CLI_ARGS) as AppError;
39
+ error.code = ERROR_CODES.INVALID_CLI_ARGS;
40
+ error.details = details;
41
+ return error;
42
+ }
43
+
44
+ function parseAgentConfigJson(raw: string, source: 'cli' | 'env'): Record<string, unknown> {
45
+ let parsed: unknown;
46
+ try {
47
+ parsed = JSON.parse(raw);
48
+ } catch (error) {
49
+ throw invalidAgentConfigError({
50
+ reason: 'Invalid agent config JSON',
51
+ source,
52
+ value: raw,
53
+ parse_error: error instanceof Error ? error.message : String(error)
54
+ });
55
+ }
56
+
57
+ if (!isPlainObject(parsed)) {
58
+ throw invalidAgentConfigError({
59
+ reason: 'Agent config JSON must be an object',
60
+ source,
61
+ value: raw
62
+ });
63
+ }
64
+
65
+ return parsed;
66
+ }
67
+
68
+ function resolveConfiguredAgentConfig(
69
+ provider: string,
70
+ runtime: ResolveSelectionRuntimeConfig
71
+ ): Record<string, unknown> | null {
72
+ if (!runtime) {
73
+ return null;
74
+ }
75
+
76
+ const providerSpecific = runtime.provider_configs?.[provider];
77
+ if (isPlainObject(providerSpecific)) {
78
+ return providerSpecific;
79
+ }
80
+
81
+ if (isPlainObject(runtime.default_agent_config)) {
82
+ return runtime.default_agent_config;
83
+ }
84
+
85
+ return null;
86
+ }
87
+
88
+ export const SUPPORTED_PROVIDERS = new Set<ProviderSelection['provider']>([
89
+ 'codex',
90
+ 'claude',
91
+ 'gemini',
92
+ 'custom',
93
+ 'kiro-cli',
94
+ 'copilot'
95
+ ]);
96
+ export const AUTH_REQUIRED_PROVIDERS = new Set<ProviderSelection['provider']>(['codex', 'claude', 'gemini']);
29
97
  export type ProviderSelectionResolver = (input: ResolveSelectionInput) => ProviderSelection;
30
98
 
31
99
  export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env, agentsConfig }) => {
@@ -60,7 +128,10 @@ export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env,
60
128
  throw error;
61
129
  }
62
130
 
63
- if (provider !== 'custom' && (!providerConfigEnv || !env[providerConfigEnv])) {
131
+ if (
132
+ AUTH_REQUIRED_PROVIDERS.has(provider as ProviderSelection['provider']) &&
133
+ (!providerConfigEnv || !env[providerConfigEnv])
134
+ ) {
64
135
  const error = new Error(ERROR_CODES.PROVIDER_AUTH_MISSING) as AppError;
65
136
  error.code = ERROR_CODES.PROVIDER_AUTH_MISSING;
66
137
  error.details = {
@@ -70,11 +141,21 @@ export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env,
70
141
  throw error;
71
142
  }
72
143
 
144
+ const agentConfig =
145
+ typeof cli.agent_config === 'string' && cli.agent_config.length > 0
146
+ ? parseAgentConfigJson(cli.agent_config, 'cli')
147
+ : typeof env.AOP_AGENT_CONFIG === 'string' && env.AOP_AGENT_CONFIG.length > 0
148
+ ? parseAgentConfigJson(env.AOP_AGENT_CONFIG, 'env')
149
+ : typeof env.AOP_AGENT_CONFIG_JSON === 'string' && env.AOP_AGENT_CONFIG_JSON.length > 0
150
+ ? parseAgentConfigJson(env.AOP_AGENT_CONFIG_JSON, 'env')
151
+ : resolveConfiguredAgentConfig(provider, agentsConfig?.runtime);
152
+
73
153
  return {
74
154
  provider: provider as ProviderSelection['provider'],
75
155
  model: model ?? `${provider}-default`,
76
156
  provider_config_env: providerConfigEnv,
77
- provider_config_ref: providerConfigEnv ? env[providerConfigEnv] ?? null : null
157
+ provider_config_ref: providerConfigEnv ? env[providerConfigEnv] ?? null : null,
158
+ agent_config: agentConfig
78
159
  };
79
160
  };
80
161
 
@@ -18,6 +18,8 @@ describe('cli helper modules', () => {
18
18
  'run',
19
19
  '--agent-model',
20
20
  'gpt-5',
21
+ '--agent-config',
22
+ '{"command":"kiro-cli","args":["chat","--agent","dev"]}',
21
23
  '--provider-config-env',
22
24
  'AOP_PROVIDER_CFG',
23
25
  '--transport',
@@ -27,6 +29,7 @@ describe('cli helper modules', () => {
27
29
  expect(parsed).toMatchObject({
28
30
  command: 'run',
29
31
  agent_model: 'gpt-5',
32
+ agent_config: '{"command":"kiro-cli","args":["chat","--agent","dev"]}',
30
33
  provider_config_env: 'AOP_PROVIDER_CFG',
31
34
  transport: 'mcp'
32
35
  });
@@ -87,6 +87,84 @@ describe('provider selection', () => {
87
87
  expect(selection.provider).toBe('custom');
88
88
  expect(selection.provider_config_ref).toBeNull();
89
89
  });
90
+
91
+ it('GIVEN_kiro_cli_provider_without_credentials_WHEN_resolving_THEN_allows_null_config_ref', () => {
92
+ const selection = resolveProviderSelection({
93
+ cli: {
94
+ agent_provider: 'kiro-cli'
95
+ },
96
+ env: {},
97
+ agentsConfig: {}
98
+ });
99
+
100
+ expect(selection.provider).toBe('kiro-cli');
101
+ expect(selection.provider_config_ref).toBeNull();
102
+ });
103
+
104
+ it('GIVEN_provider_configured_agent_config_WHEN_resolving_THEN_returns_provider_specific_config', () => {
105
+ const selection = resolveProviderSelection({
106
+ cli: {
107
+ agent_provider: 'kiro-cli'
108
+ },
109
+ env: {},
110
+ agentsConfig: {
111
+ runtime: {
112
+ provider_configs: {
113
+ 'kiro-cli': {
114
+ command: 'kiro-cli',
115
+ args: ['chat', '--agent', 'dev']
116
+ }
117
+ }
118
+ }
119
+ }
120
+ });
121
+
122
+ expect(selection.agent_config).toEqual({
123
+ command: 'kiro-cli',
124
+ args: ['chat', '--agent', 'dev']
125
+ });
126
+ });
127
+
128
+ it('GIVEN_cli_agent_config_WHEN_resolving_THEN_cli_agent_config_overrides_runtime_defaults', () => {
129
+ const selection = resolveProviderSelection({
130
+ cli: {
131
+ agent_provider: 'copilot',
132
+ agent_config: JSON.stringify({
133
+ command: 'copilot',
134
+ args: ['chat', '--agent', 'review']
135
+ })
136
+ },
137
+ env: {},
138
+ agentsConfig: {
139
+ runtime: {
140
+ provider_configs: {
141
+ copilot: {
142
+ command: 'copilot',
143
+ args: ['chat']
144
+ }
145
+ }
146
+ }
147
+ }
148
+ });
149
+
150
+ expect(selection.agent_config).toEqual({
151
+ command: 'copilot',
152
+ args: ['chat', '--agent', 'review']
153
+ });
154
+ });
155
+
156
+ it('GIVEN_invalid_cli_agent_config_json_WHEN_resolving_THEN_throws_invalid_cli_args', () => {
157
+ expect(() =>
158
+ resolveProviderSelection({
159
+ cli: {
160
+ agent_provider: 'kiro-cli',
161
+ agent_config: '{not-json'
162
+ },
163
+ env: {},
164
+ agentsConfig: {}
165
+ })
166
+ ).toThrow(ERROR_CODES.INVALID_CLI_ARGS);
167
+ });
90
168
  });
91
169
 
92
170
  describe('NullWorkerProvider', () => {
@@ -24,3 +24,5 @@ Important:
24
24
  - For Java projects, use the Java `gates.yaml` Maven commands (`./mvnw ...`) and `jacoco_xml` parser.
25
25
  - `policy.yaml -> supervisor.max_iterations_per_phase` controls planner/builder/qa loop reconciliation iterations (default `6`).
26
26
  - `policy.yaml -> rbac.orchestrator` includes `feature.delete` for the delete command path.
27
+ - `agents.yaml -> runtime.default_provider` supports `kiro-cli` and `copilot` in addition to existing providers.
28
+ - `agents.yaml -> runtime.provider_configs.<provider>` can hold provider-specific command payloads (for example `command: kiro-cli`, `args: [chat, --agent, dev]`).
@@ -11,4 +11,14 @@ runtime:
11
11
  default_provider: custom
12
12
  default_model: java-default
13
13
  provider_config_env: JAVA_PROVIDER_CONFIG_ENV
14
+ provider_configs:
15
+ kiro-cli:
16
+ command: kiro-cli
17
+ args:
18
+ - chat
19
+ - --agent
20
+ - dev
21
+ copilot:
22
+ command: copilot
23
+ args: []
14
24
  role_provider_overrides: {}
@@ -11,4 +11,14 @@ runtime:
11
11
  default_provider: custom
12
12
  default_model: node-default
13
13
  provider_config_env: NODE_PROVIDER_CONFIG_ENV
14
+ provider_configs:
15
+ kiro-cli:
16
+ command: kiro-cli
17
+ args:
18
+ - chat
19
+ - --agent
20
+ - dev
21
+ copilot:
22
+ command: copilot
23
+ args: []
14
24
  role_provider_overrides: {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-orchestrator",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "MCP-first, platform-agnostic multi-agent orchestrator control plane",