@gajae-code/coding-agent 0.14.2 → 0.15.0
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 +120 -1
- package/dist/types/async/job-manager.d.ts +4 -1
- package/dist/types/autoresearch/dashboard.d.ts +29 -4
- package/dist/types/autoresearch/data-context.d.ts +25 -0
- package/dist/types/autoresearch/git.d.ts +65 -7
- package/dist/types/autoresearch/harness.d.ts +58 -0
- package/dist/types/autoresearch/prompts.d.ts +51 -0
- package/dist/types/autoresearch/runs.d.ts +173 -0
- package/dist/types/autoresearch/types.d.ts +9 -139
- package/dist/types/capability/types.d.ts +20 -0
- package/dist/types/cli/accounts-cli.d.ts +1 -0
- package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
- package/dist/types/config/autorouting-contract.d.ts +146 -0
- package/dist/types/config/autorouting-generator.d.ts +40 -0
- package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
- package/dist/types/config/autorouting.d.ts +35 -0
- package/dist/types/config/model-discovery-manager.d.ts +8 -1
- package/dist/types/config/model-registry.d.ts +30 -1
- package/dist/types/config/provider-selection-policy.d.ts +23 -0
- package/dist/types/config/settings-schema.d.ts +61 -3
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/durability.d.ts +29 -0
- package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
- package/dist/types/coordinator-mcp/server.d.ts +14 -0
- package/dist/types/crash/index-store.d.ts +3 -0
- package/dist/types/crash/record-loader.d.ts +2 -0
- package/dist/types/crash/upstream/relay.d.ts +5 -3
- package/dist/types/cursor.d.ts +12 -0
- package/dist/types/defaults/gjc-defaults.d.ts +35 -1
- package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
- package/dist/types/discovery/helpers.d.ts +1 -1
- package/dist/types/edit/index.d.ts +2 -1
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/loader.d.ts +32 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
- package/dist/types/extensibility/skills.d.ts +2 -0
- package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
- package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
- package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
- package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
- package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
- package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
- package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
- package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
- package/dist/types/hooks/skill-keywords.d.ts +1 -1
- package/dist/types/main.d.ts +0 -10
- package/dist/types/modes/acp/acp-agent.d.ts +13 -6
- package/dist/types/modes/components/model-selector.d.ts +14 -0
- package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
- package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/types.d.ts +9 -0
- package/dist/types/rlm/artifacts.d.ts +4 -4
- package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
- package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
- package/dist/types/runtime-mcp/config.d.ts +6 -0
- package/dist/types/runtime-mcp/manager.d.ts +10 -0
- package/dist/types/sdk/acp/adapter.d.ts +0 -4
- package/dist/types/sdk/broker/broker.d.ts +1 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
- package/dist/types/sdk/broker/session-index.d.ts +15 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/index.d.ts +8 -0
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
- package/dist/types/sdk/client/client.d.ts +39 -4
- package/dist/types/sdk/host/host.d.ts +1 -0
- package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
- package/dist/types/sdk/host/model-pin.d.ts +29 -0
- package/dist/types/sdk/host/session-runtime.d.ts +2 -1
- package/dist/types/sdk/lifecycle-session.d.ts +13 -0
- package/dist/types/sdk/router/session-router.d.ts +27 -1
- package/dist/types/sdk/session.d.ts +11 -1
- package/dist/types/session/agent-session.d.ts +36 -6
- package/dist/types/session/artifacts.d.ts +16 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
- package/dist/types/session/session-manager.d.ts +84 -2
- package/dist/types/session/session-staging-paths.d.ts +3 -0
- package/dist/types/skill-state/canonical-skills.d.ts +1 -1
- package/dist/types/skill-state/workflow-hud.d.ts +12 -21
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
- package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
- package/dist/types/system-prompt.d.ts +23 -0
- package/dist/types/task/executor.d.ts +35 -4
- package/dist/types/task/index.d.ts +17 -3
- package/dist/types/task/receipt.d.ts +3 -1
- package/dist/types/task/types.d.ts +144 -0
- package/dist/types/tools/atomic-file-write.d.ts +72 -0
- package/dist/types/tools/descriptors.d.ts +1 -0
- package/dist/types/tools/index.d.ts +36 -1
- package/dist/types/tools/move-session.d.ts +40 -0
- package/dist/types/tools/python.d.ts +12 -0
- package/dist/types/tools/resource-gc.d.ts +0 -3
- package/dist/types/tools/search.d.ts +8 -1
- package/dist/types/tools/skill.d.ts +9 -4
- package/dist/types/tools/subagent.d.ts +33 -3
- package/dist/types/utils/xml-escape.d.ts +2 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
- package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
- package/package.json +11 -12
- package/scripts/build-sdk-package-smoke.ts +7 -5
- package/scripts/check-autorouting-tier-map.ts +183 -0
- package/scripts/generate-sdk-operation-inventory.ts +12 -0
- package/scripts/generate-tool-catalog.ts +40 -5
- package/src/async/job-manager.ts +5 -2
- package/src/autoresearch/dashboard.ts +134 -314
- package/src/autoresearch/data-context.ts +35 -0
- package/src/autoresearch/git.ts +186 -26
- package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
- package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
- package/src/autoresearch/prompts/prompt.md +103 -0
- package/src/autoresearch/prompts.ts +126 -0
- package/src/autoresearch/runs.ts +708 -0
- package/src/autoresearch/types.ts +9 -150
- package/src/capability/index.ts +4 -4
- package/src/capability/types.ts +20 -0
- package/src/cli/accounts-cli.ts +21 -5
- package/src/cli/config-cli.ts +25 -1
- package/src/cli/fast-help.ts +1 -2
- package/src/cli/list-models.ts +5 -8
- package/src/cli/setup-cli.ts +8 -0
- package/src/cli.ts +2 -21
- package/src/commands/autoresearch.ts +33 -0
- package/src/commands/coordinator.ts +15 -0
- package/src/commands/launch.ts +2 -4
- package/src/commands/quick-lane.ts +1 -1
- package/src/commands/sdk.ts +24 -0
- package/src/commands/state.ts +1 -1
- package/src/config/autorouting-contract.ts +474 -0
- package/src/config/autorouting-generator.ts +238 -0
- package/src/config/autorouting-tier-map.ts +6108 -0
- package/src/config/autorouting.ts +120 -0
- package/src/config/model-discovery-manager.ts +42 -11
- package/src/config/model-registry.ts +348 -68
- package/src/config/provider-selection-policy.ts +60 -9
- package/src/config/settings-schema.ts +195 -6
- package/src/config/settings.ts +62 -1
- package/src/config.ts +2 -3
- package/src/coordinator/contract.ts +0 -1
- package/src/coordinator-mcp/codex-handoff.ts +68 -42
- package/src/coordinator-mcp/durability.ts +200 -0
- package/src/coordinator-mcp/event-webhook.ts +278 -0
- package/src/coordinator-mcp/question-state.ts +109 -46
- package/src/coordinator-mcp/server.ts +932 -504
- package/src/crash/index-store.ts +126 -22
- package/src/crash/record-loader.ts +7 -0
- package/src/crash/upstream/relay.ts +82 -34
- package/src/cursor.ts +84 -1
- package/src/debug/index.ts +26 -0
- package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
- package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
- package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
- package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
- package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
- package/src/defaults/gjc-defaults.ts +89 -2
- package/src/defaults/gjc-skills.generated.ts +24 -17
- package/src/discovery/builtin.ts +18 -5
- package/src/discovery/helpers.ts +6 -6
- package/src/edit/index.ts +5 -2
- package/src/eval/py/executor.ts +8 -0
- package/src/extensibility/extensions/loader.ts +135 -13
- package/src/extensibility/extensions/wrapper.ts +1 -2
- package/src/extensibility/gjc-plugins/schema.ts +1 -1
- package/src/extensibility/runtime-skill-discovery.ts +2 -2
- package/src/extensibility/skill-management.ts +2 -3
- package/src/extensibility/skills.ts +16 -8
- package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
- package/src/gjc-runtime/gc-render.ts +0 -1
- package/src/gjc-runtime/gc-runtime.ts +1 -11
- package/src/gjc-runtime/launch-tmux.ts +3 -3
- package/src/gjc-runtime/psmux-detect.ts +2 -2
- package/src/gjc-runtime/python-transcript.ts +58 -0
- package/src/gjc-runtime/ralplan-runtime.ts +6 -18
- package/src/gjc-runtime/session-layout.ts +18 -7
- package/src/gjc-runtime/session-state-sidecar.ts +58 -9
- package/src/gjc-runtime/state-renderer.ts +0 -38
- package/src/gjc-runtime/state-runtime.ts +43 -22
- package/src/gjc-runtime/state-schema.ts +1 -1
- package/src/gjc-runtime/tmux-common.ts +7 -7
- package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
- package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
- package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
- package/src/gjc-runtime/workflow-command-ref.ts +15 -11
- package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
- package/src/gjc-runtime/workflow-manifest.ts +43 -83
- package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
- package/src/hooks/skill-keywords.ts +3 -3
- package/src/hooks/skill-state.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +26 -24
- package/src/lsp/index.ts +25 -5
- package/src/main.ts +2 -27
- package/src/modes/acp/acp-agent.ts +200 -75
- package/src/modes/components/model-selector.ts +216 -13
- package/src/modes/components/oauth-selector.ts +5 -5
- package/src/modes/components/skill-hud/render.ts +173 -35
- package/src/modes/components/smart-routing-panel.ts +531 -0
- package/src/modes/components/tool-status-header.ts +6 -3
- package/src/modes/controllers/command-controller.ts +17 -7
- package/src/modes/controllers/input-controller.ts +44 -9
- package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
- package/src/modes/controllers/selector-controller.ts +298 -65
- package/src/modes/interactive-mode.ts +8 -1
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
- package/src/modes/types.ts +9 -1
- package/src/prompts/agents/planner.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/volatile-project-context.md +2 -1
- package/src/prompts/tools/move-session.md +15 -0
- package/src/prompts/tools/python.md +12 -0
- package/src/prompts/tools/skill-discovery.md +1 -1
- package/src/prompts/tools/skill.md +2 -2
- package/src/prompts/tools/task-summary.md +1 -0
- package/src/prompts/tools/task.md +6 -0
- package/src/rlm/artifacts.ts +12 -10
- package/src/runtime/optional-runtime-services.ts +3 -2
- package/src/runtime/workspace-tree-service.ts +11 -3
- package/src/runtime-mcp/config.ts +8 -1
- package/src/runtime-mcp/manager.ts +33 -0
- package/src/sdk/acp/adapter.ts +48 -1
- package/src/sdk/broker/broker.ts +30 -2
- package/src/sdk/broker/discovery.ts +217 -2
- package/src/sdk/broker/lifecycle.ts +385 -59
- package/src/sdk/broker/session-index.ts +243 -48
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +8 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
- package/src/sdk/bus/index.ts +208 -11
- package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
- package/src/sdk/bus/reconciliation-store.ts +27 -5
- package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
- package/src/sdk/client/client.ts +204 -22
- package/src/sdk/host/host.ts +16 -0
- package/src/sdk/host/internal-autorouting-state.ts +13 -0
- package/src/sdk/host/model-pin.ts +101 -0
- package/src/sdk/host/reverse-leases.ts +2 -1
- package/src/sdk/host/session-runtime.test.ts +224 -1
- package/src/sdk/host/session-runtime.ts +125 -37
- package/src/sdk/lifecycle/service.ts +3 -1
- package/src/sdk/lifecycle-session.ts +42 -1
- package/src/sdk/protocol/operation-inventory.generated.json +66 -0
- package/src/sdk/router/session-router.ts +375 -36
- package/src/sdk/session.ts +547 -47
- package/src/session/account-inventory.ts +1 -1
- package/src/session/agent-session.ts +765 -189
- package/src/session/artifacts.ts +234 -4
- package/src/session/internal/managed-session-storage.ts +91 -4
- package/src/session/provider-safety-stop-hint.ts +3 -2
- package/src/session/session-manager.ts +775 -16
- package/src/session/session-staging-paths.ts +8 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
- package/src/setup/host-plugin-setup.ts +2 -2
- package/src/skill-state/active-state.ts +2 -2
- package/src/skill-state/canonical-skills.ts +1 -1
- package/src/skill-state/initial-phase.ts +1 -1
- package/src/skill-state/workflow-hud.ts +41 -41
- package/src/skill-state/workflow-mutation-guard.ts +26 -7
- package/src/slash-commands/builtin-registry.ts +77 -0
- package/src/slash-commands/helpers/autorouting-status.ts +55 -0
- package/src/system-prompt.ts +102 -5
- package/src/task/discovery.ts +2 -3
- package/src/task/executor.ts +617 -43
- package/src/task/index.ts +262 -15
- package/src/task/receipt.ts +30 -0
- package/src/task/render.ts +11 -1
- package/src/task/types.ts +316 -0
- package/src/tools/atomic-file-write.ts +594 -0
- package/src/tools/bisect.ts +3 -2
- package/src/tools/descriptors.test.ts +3 -0
- package/src/tools/descriptors.ts +24 -0
- package/src/tools/image-gen.ts +5 -1
- package/src/tools/index.ts +62 -5
- package/src/tools/move-session.ts +107 -0
- package/src/tools/python.ts +205 -0
- package/src/tools/read.ts +88 -15
- package/src/tools/renderers.ts +2 -0
- package/src/tools/resource-gc.ts +8 -177
- package/src/tools/search.ts +30 -6
- package/src/tools/skill-discovery.ts +1 -0
- package/src/tools/skill.ts +37 -7
- package/src/tools/subagent-render.ts +119 -13
- package/src/tools/subagent.ts +91 -74
- package/src/tools/tool-catalog.generated.ts +64 -2
- package/src/tools/write.ts +16 -12
- package/src/utils/xml-escape.ts +14 -0
- package/src/web/search/providers/codex.ts +2 -2
- package/src/workflow/workflow-intent-diff.ts +13 -12
- package/src/workflow/workflow-intent-report-consumer.ts +6 -6
- package/dist/types/autoresearch/helpers.d.ts +0 -24
- package/dist/types/autoresearch/index.d.ts +0 -2
- package/dist/types/autoresearch/state.d.ts +0 -17
- package/dist/types/autoresearch/storage.d.ts +0 -142
- package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
- package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
- package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
- package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
- package/dist/types/commands/team.d.ts +0 -24
- package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
- package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
- package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
- package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
- package/dist/types/gjc-runtime/team-store.d.ts +0 -168
- package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
- package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
- package/dist/types/rlm/index.d.ts +0 -47
- package/dist/types/rlm/preset.d.ts +0 -23
- package/dist/types/rlm/python-tool.d.ts +0 -16
- package/src/autoresearch/command-resume.md +0 -14
- package/src/autoresearch/index.ts +0 -536
- package/src/autoresearch/prompt.md +0 -103
- package/src/autoresearch/resume-message.md +0 -10
- package/src/autoresearch/state.ts +0 -273
- package/src/autoresearch/storage.ts +0 -699
- package/src/autoresearch/tools/init-experiment.ts +0 -272
- package/src/autoresearch/tools/log-experiment.ts +0 -524
- package/src/autoresearch/tools/run-experiment.ts +0 -475
- package/src/autoresearch/tools/update-notes.ts +0 -109
- package/src/commands/rlm.ts +0 -19
- package/src/commands/team.ts +0 -238
- package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
- package/src/defaults/gjc/skills/team/SKILL.md +0 -467
- package/src/gjc-runtime/team-gc.ts +0 -49
- package/src/gjc-runtime/team-launch.ts +0 -404
- package/src/gjc-runtime/team-notify.ts +0 -326
- package/src/gjc-runtime/team-runtime.ts +0 -5923
- package/src/gjc-runtime/team-store.ts +0 -878
- package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
- package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
- package/src/gjc-runtime/team-workers.ts +0 -1123
- package/src/prompts/system/rlm-report-command.md +0 -1
- package/src/prompts/system/rlm-research.md +0 -23
- package/src/rlm/index.ts +0 -365
- package/src/rlm/preset.ts +0 -76
- package/src/rlm/python-tool.ts +0 -68
|
@@ -10,10 +10,15 @@
|
|
|
10
10
|
* project/user skills have no native workflow mode-state, so they are dispatched
|
|
11
11
|
* directly and tracked by the prompt observer instead.
|
|
12
12
|
*
|
|
13
|
-
* Canonical workflow chaining is refused unless the caller's
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Canonical workflow chaining is refused unless the caller's phase permits it:
|
|
14
|
+
* the generic terminal set `{complete, completed, handoff, failed, cancelled,
|
|
15
|
+
* canceled, inactive}`, the caller's manifest-declared terminal states (e.g.
|
|
16
|
+
* ralplan `final`), or — for autoresearch only — any phase with a declared
|
|
17
|
+
* handoff edge (`intake`/`research`/`verdict`): a research mission never
|
|
18
|
+
* mutates and guards no approval gate, its mission state is durable, so an
|
|
19
|
+
* ongoing or verdict-complete mission may hand off to planning at any point.
|
|
20
|
+
* ralplan/ultragoal keep the explicit write-to-handoff step for live phases:
|
|
21
|
+
* their mid-flight chaining is exactly what the approval-gate guard blocks.
|
|
17
22
|
*/
|
|
18
23
|
import type { AgentTool, AgentToolResult } from "@gajae-code/agent-core";
|
|
19
24
|
import * as z from "zod/v4";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core";
|
|
2
2
|
import * as z from "zod/v4";
|
|
3
|
-
import type { AgentProgress, AgentSource } from "../task/types";
|
|
3
|
+
import type { AgentProgress, AgentSource, LocalErrorSummary } from "../task/types";
|
|
4
4
|
import type { ToolSession } from "./index";
|
|
5
5
|
declare const subagentSchema: z.ZodObject<{
|
|
6
6
|
action: z.ZodEnum<{
|
|
@@ -45,6 +45,8 @@ export interface SubagentSnapshot {
|
|
|
45
45
|
errorText?: string;
|
|
46
46
|
/** Safe setup failure cause retained from the executor launch path. */
|
|
47
47
|
setupFailureSummary?: string;
|
|
48
|
+
/** Safe, bounded summary of a terminal local (non-provider) failure (e.g. local_buffer_overflow). */
|
|
49
|
+
localErrorSummary?: LocalErrorSummary;
|
|
48
50
|
resultPreview?: string;
|
|
49
51
|
outputRef?: string;
|
|
50
52
|
truncated?: boolean;
|
|
@@ -52,8 +54,8 @@ export interface SubagentSnapshot {
|
|
|
52
54
|
steerMessage?: string;
|
|
53
55
|
steerState?: "queued" | "resume_queued" | "resume_started";
|
|
54
56
|
steerPauseRequested?: boolean;
|
|
55
|
-
/**
|
|
56
|
-
progress?:
|
|
57
|
+
/** Bounded live progress approved for the await panel and public tool details. */
|
|
58
|
+
progress?: SubagentLiveProgress;
|
|
57
59
|
/** True when a live in-session progress producer exists for this subagent. */
|
|
58
60
|
liveProgressAvailable?: boolean;
|
|
59
61
|
/** Model the subagent actually runs on (after any auth fallback). */
|
|
@@ -65,6 +67,34 @@ export interface SubagentSnapshot {
|
|
|
65
67
|
/** True when the effective subagent provider is in fast mode. */
|
|
66
68
|
fastMode?: boolean;
|
|
67
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Public await-panel progress. This is deliberately not `AgentProgress`: raw
|
|
72
|
+
* progress contains model deltas, tool arguments, arbitrary output, and nested
|
|
73
|
+
* task payloads that must never enter tool-result, ACP, or telemetry envelopes.
|
|
74
|
+
*/
|
|
75
|
+
export interface SubagentLiveProgress {
|
|
76
|
+
id: string;
|
|
77
|
+
status: AgentProgress["status"];
|
|
78
|
+
currentTool?: string;
|
|
79
|
+
recentTool?: string;
|
|
80
|
+
recentOutputSummary?: {
|
|
81
|
+
lineCount: number;
|
|
82
|
+
};
|
|
83
|
+
fastMode?: boolean;
|
|
84
|
+
retryState?: {
|
|
85
|
+
attempt: number;
|
|
86
|
+
maxAttempts: number;
|
|
87
|
+
unbounded?: boolean;
|
|
88
|
+
kind: NonNullable<AgentProgress["retryState"]>["kind"];
|
|
89
|
+
provider?: string;
|
|
90
|
+
lastProviderProgressAtMs?: number;
|
|
91
|
+
delayMs: number;
|
|
92
|
+
startedAtMs: number;
|
|
93
|
+
};
|
|
94
|
+
retryFailure?: {
|
|
95
|
+
attempt: number;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
68
98
|
export type SubagentAwaitOutcome = "completed" | "timed_out" | "interrupted";
|
|
69
99
|
export interface SubagentToolDetails {
|
|
70
100
|
subagents: SubagentSnapshot[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type WorkflowClaimsLedger, type WorkflowConsensusReport } from "./workflow-intent-report";
|
|
2
2
|
export declare const WORKFLOW_INTENT_DIFF_CUSTOM_TYPE = "workflow-intent-diff";
|
|
3
|
-
export declare const WORKFLOW_INTENT_ROUTES: readonly ["direct", "deep-interview", "ralplan", "ultragoal", "
|
|
4
|
-
export declare const WORKFLOW_ESCALATION_ROUTES: readonly ["deep-interview", "ralplan", "ultragoal", "
|
|
3
|
+
export declare const WORKFLOW_INTENT_ROUTES: readonly ["direct", "deep-interview", "ralplan", "ultragoal", "autoresearch"];
|
|
4
|
+
export declare const WORKFLOW_ESCALATION_ROUTES: readonly ["deep-interview", "ralplan", "ultragoal", "autoresearch"];
|
|
5
5
|
export type WorkflowIntentRoute = (typeof WORKFLOW_INTENT_ROUTES)[number];
|
|
6
6
|
export type WorkflowEscalationRoute = (typeof WORKFLOW_ESCALATION_ROUTES)[number];
|
|
7
7
|
export type DirectTrackingMode = "custom-entry-only" | "not-direct";
|
|
@@ -7,7 +7,7 @@ export interface WorkflowRouteCounts {
|
|
|
7
7
|
readonly "deep-interview": number;
|
|
8
8
|
readonly ralplan: number;
|
|
9
9
|
readonly ultragoal: number;
|
|
10
|
-
readonly
|
|
10
|
+
readonly autoresearch: number;
|
|
11
11
|
}
|
|
12
12
|
export interface WorkflowIntentReportEntry {
|
|
13
13
|
readonly entryId: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"description": "Gajae Code CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"check": "biome check . && bun run check:types",
|
|
34
34
|
"check:runtime": "bun run generate-hotkeys-docs --check && bun run verify:sdk-canonicalization",
|
|
35
35
|
"check:types": "tsc -p tsconfig.json --noEmit",
|
|
36
|
+
"check:autorouting-map": "bun scripts/check-autorouting-tier-map.ts",
|
|
36
37
|
"lint": "biome lint .",
|
|
37
38
|
"test": "bun test",
|
|
38
39
|
"generate-hotkeys-docs": "bun scripts/generate-hotkeys-docs.ts",
|
|
@@ -55,12 +56,12 @@
|
|
|
55
56
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
56
57
|
"@babel/parser": "^7.29.3",
|
|
57
58
|
"@mozilla/readability": "^0.6.0",
|
|
58
|
-
"@gajae-code/stats": "0.
|
|
59
|
-
"@gajae-code/agent-core": "0.
|
|
60
|
-
"@gajae-code/ai": "0.
|
|
61
|
-
"@gajae-code/natives": "0.
|
|
62
|
-
"@gajae-code/tui": "0.
|
|
63
|
-
"@gajae-code/utils": "0.
|
|
59
|
+
"@gajae-code/stats": "0.15.0",
|
|
60
|
+
"@gajae-code/agent-core": "0.15.0",
|
|
61
|
+
"@gajae-code/ai": "0.15.0",
|
|
62
|
+
"@gajae-code/natives": "0.15.0",
|
|
63
|
+
"@gajae-code/tui": "0.15.0",
|
|
64
|
+
"@gajae-code/utils": "0.15.0",
|
|
64
65
|
"@puppeteer/browsers": "^2.13.0",
|
|
65
66
|
"@types/turndown": "5.0.6",
|
|
66
67
|
"@xterm/headless": "^6.0.0",
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
"@types/ws": "^8.5.13"
|
|
86
87
|
},
|
|
87
88
|
"engines": {
|
|
88
|
-
"bun": ">=1.
|
|
89
|
+
"bun": ">=1.4.0"
|
|
89
90
|
},
|
|
90
91
|
"files": [
|
|
91
92
|
"src",
|
|
@@ -150,6 +151,8 @@
|
|
|
150
151
|
"./sdk/host/control/runtime-gate.js": null,
|
|
151
152
|
"./sdk/host/control/runtime-gate": null,
|
|
152
153
|
"./sdk/host/control/runtime-gate/*": null,
|
|
154
|
+
"./sdk/host/internal-autorouting-state.js": null,
|
|
155
|
+
"./sdk/host/internal-autorouting-state": null,
|
|
153
156
|
"./sdk/lifecycle/broker-client.js": null,
|
|
154
157
|
"./sdk/lifecycle/broker-client": null,
|
|
155
158
|
"./sdk/lifecycle/broker-client/*": null,
|
|
@@ -200,10 +203,6 @@
|
|
|
200
203
|
"types": "./dist/types/cli/commands/*.d.ts",
|
|
201
204
|
"import": "./src/cli/commands/*.ts"
|
|
202
205
|
},
|
|
203
|
-
"./autoresearch": null,
|
|
204
|
-
"./autoresearch/*": null,
|
|
205
|
-
"./autoresearch/tools/*": null,
|
|
206
|
-
"./commands/autoresearch": null,
|
|
207
206
|
"./commands/ralph": null,
|
|
208
207
|
"./commands/ultraqa": null,
|
|
209
208
|
"./commands/ultrawork": null,
|
|
@@ -25,7 +25,8 @@ function run(command: string[], cwd: string): string {
|
|
|
25
25
|
if (result.exitCode !== 0) {
|
|
26
26
|
throw new Error(`${command.join(" ")} failed:\n${new TextDecoder().decode(result.stderr)}`);
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
const lines = new TextDecoder().decode(result.stdout).trim().split(/\r?\n/);
|
|
29
|
+
return lines.at(-1) ?? "";
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
function assertExport(module: Record<string, unknown>, name: string, subpath: string): void {
|
|
@@ -95,9 +96,10 @@ async function runSmoke(): Promise<Surface> {
|
|
|
95
96
|
// Install the matching packed workspace artifacts so the smoke test exercises the
|
|
96
97
|
// release dependency boundary without falling back to an older registry package.
|
|
97
98
|
run(["bun", "install", "--ignore-scripts"], tempDir);
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
const stagedPackageJsonPath = path.join(tempDir, "node_modules", packageName, "package.json");
|
|
100
|
+
const installedPackage = JSON.parse(await fs.readFile(stagedPackageJsonPath, "utf8")) as {
|
|
101
|
+
exports?: Record<string, unknown>;
|
|
102
|
+
};
|
|
101
103
|
const installedAgentPackagePath = path.join(tempDir, "node_modules", "@gajae-code", "agent-core");
|
|
102
104
|
const installedAgentPackageJsonPath = path.join(installedAgentPackagePath, "package.json");
|
|
103
105
|
const installedAgentPackage = JSON.parse(await fs.readFile(installedAgentPackageJsonPath, "utf8")) as {
|
|
@@ -150,7 +152,7 @@ async function runSmoke(): Promise<Surface> {
|
|
|
150
152
|
const probePath = path.join(tempDir, "probe.ts");
|
|
151
153
|
await fs.writeFile(
|
|
152
154
|
probePath,
|
|
153
|
-
`import * as fs from "node:fs/promises";\nimport * as path from "node:path";\nimport * as root from ${JSON.stringify(packageName)};\nimport * as sdk from ${JSON.stringify(`${packageName}/sdk`)};\nimport * as bus from ${JSON.stringify(`${packageName}/sdk/bus`)};\nconst required = [[root, "createAgentSession", "root"], [root, "SESSION_DIRECTORY_API_VERSION", "root"], [root, "resolveManagedSessionScope", "root"], [root, "listManagedSessionCandidates", "root"], [sdk, "createAgentSession", "sdk"], [bus, "createNotificationsExtension", "sdk/bus"], [sdk, "SESSION_DIRECTORY_API_VERSION", "sdk"], [sdk, "resolveManagedSessionScope", "sdk"], [sdk, "listManagedSessionCandidates", "sdk"]] as const;\nfor (const [module, name, subpath] of required) if (!(name in module)) throw new Error(subpath + " missing " + name);\nconst sandbox = path.join(process.cwd(), "managed-listing-smoke");\nconst cwd = path.join(sandbox, "workspace", "a-b", "c");\nconst agentDir = path.join(sandbox, "agent");\nconst sessionsRoot = path.join(agentDir, "sessions");\nawait fs.mkdir(cwd, { recursive: true });\nconst resolved = await sdk.resolveManagedSessionScope({ cwd, agentDir, sessionsRoot });\nif (resolved.kind !== "resolved") throw new Error("packed resolver failed: " + resolved.message);\nawait fs.mkdir(resolved.scope.directoryPath, { recursive: true, mode: 0o700 });\nawait fs.chmod(sessionsRoot, 0o700);\nawait fs.chmod(resolved.scope.directoryPath, 0o700);\nawait fs.writeFile(path.join(resolved.scope.directoryPath, ".gjc-managed-session-scope.v2.json"), JSON.stringify({ schemaVersion: 1, layoutVersion: 2, identityVersion: 1, platform: process.platform === "win32" ? "win32" : "posix", canonicalPath: resolved.scope.canonicalCwd, identityDigest: resolved.scope.directoryName.slice(3) }) + "\\n", { mode: 0o600 });\nconst transcriptPath = path.join(resolved.scope.directoryPath, "packed-session.jsonl");\nawait fs.writeFile(transcriptPath, JSON.stringify({ type: "session", id: "packed-session", cwd }) + "\\n", { mode: 0o600 });\nconst snapshot = async () => Promise.all((await fs.readdir(sandbox, { recursive: true })).sort().map(async name => { const pathname = path.join(sandbox, name); const stat = await fs.lstat(pathname); return [name, stat.mode, stat.size, stat.mtimeMs, stat.isFile() ? await fs.readFile(pathname, "utf8") : null]; }));\nconst before = JSON.stringify(await snapshot());\nconst listing = await sdk.listManagedSessionCandidates({ scope: resolved.scope });\nif (listing.kind !== "complete" || listing.owned.length !== 1 || listing.owned[0]?.sessionId !== "packed-session") throw new Error("packed readonly listing failed: " + JSON.stringify(listing));\nconst after = JSON.stringify(await snapshot());\nif (after !== before) throw new Error("packed readonly listing mutated the filesystem");\nconst privateSubpath = ${JSON.stringify(`${packageName}/session/internal/managed-session-scope`)};\ntry { await import(privateSubpath); throw new Error("private managed-session scope subpath resolved"); } catch (error) {\n\tif (error instanceof Error && error.message === "private managed-session scope subpath resolved") throw error;\n\tconst message = String(error);\n\tconst exportsRejected = /Package subpath .* is not defined by "exports"/.test(message);\n\tconst bunRejected = message.startsWith("ResolveMessage: Cannot find module '" + privateSubpath + "' from '") && message.endsWith("/probe.ts'");\n\tif (!exportsRejected && !bunRejected) throw new Error("private managed-session scope failed for an unexpected reason: " + message);\n}\nprocess.stdout.write(JSON.stringify({ root: Object.keys(root).sort(), sdk: Object.keys(sdk).sort() }));\n`,
|
|
155
|
+
`import * as fs from "node:fs/promises";\nimport * as path from "node:path";\nimport * as root from ${JSON.stringify(packageName)};\nimport * as sdk from ${JSON.stringify(`${packageName}/sdk`)};\nimport * as bus from ${JSON.stringify(`${packageName}/sdk/bus`)};\nconst required = [[root, "createAgentSession", "root"], [root, "SESSION_DIRECTORY_API_VERSION", "root"], [root, "resolveManagedSessionScope", "root"], [root, "listManagedSessionCandidates", "root"], [sdk, "createAgentSession", "sdk"], [bus, "createNotificationsExtension", "sdk/bus"], [sdk, "SESSION_DIRECTORY_API_VERSION", "sdk"], [sdk, "resolveManagedSessionScope", "sdk"], [sdk, "listManagedSessionCandidates", "sdk"]] as const;\nfor (const [module, name, subpath] of required) if (!(name in module)) throw new Error(subpath + " missing " + name);\nconst sandbox = path.join(process.cwd(), "managed-listing-smoke");\nconst cwd = path.join(sandbox, "workspace", "a-b", "c");\nconst agentDir = path.join(sandbox, "agent");\nconst sessionsRoot = path.join(agentDir, "sessions");\nawait fs.mkdir(cwd, { recursive: true });\nconst resolved = await sdk.resolveManagedSessionScope({ cwd, agentDir, sessionsRoot });\nif (resolved.kind !== "resolved") throw new Error("packed resolver failed: " + resolved.message);\nawait fs.mkdir(resolved.scope.directoryPath, { recursive: true, mode: 0o700 });\nawait fs.chmod(sessionsRoot, 0o700);\nawait fs.chmod(resolved.scope.directoryPath, 0o700);\nawait fs.writeFile(path.join(resolved.scope.directoryPath, ".gjc-managed-session-scope.v2.json"), JSON.stringify({ schemaVersion: 1, layoutVersion: 2, identityVersion: 1, platform: process.platform === "win32" ? "win32" : "posix", canonicalPath: resolved.scope.canonicalCwd, identityDigest: resolved.scope.directoryName.slice(3) }) + "\\n", { mode: 0o600 });\nconst transcriptPath = path.join(resolved.scope.directoryPath, "packed-session.jsonl");\nawait fs.writeFile(transcriptPath, JSON.stringify({ type: "session", id: "packed-session", cwd }) + "\\n", { mode: 0o600 });\nconst snapshot = async () => Promise.all((await fs.readdir(sandbox, { recursive: true })).sort().map(async name => { const pathname = path.join(sandbox, name); const stat = await fs.lstat(pathname); return [name, stat.mode, stat.size, stat.mtimeMs, stat.isFile() ? await fs.readFile(pathname, "utf8") : null]; }));\nconst before = JSON.stringify(await snapshot());\nconst listing = await sdk.listManagedSessionCandidates({ scope: resolved.scope });\nif (listing.kind !== "complete" || listing.owned.length !== 1 || listing.owned[0]?.sessionId !== "packed-session") throw new Error("packed readonly listing failed: " + JSON.stringify(listing));\nconst after = JSON.stringify(await snapshot());\nif (after !== before) throw new Error("packed readonly listing mutated the filesystem");\nconst privateSubpath = ${JSON.stringify(`${packageName}/session/internal/managed-session-scope`)};\ntry { await import(privateSubpath); throw new Error("private managed-session scope subpath resolved"); } catch (error) {\n\tif (error instanceof Error && error.message === "private managed-session scope subpath resolved") throw error;\n\tconst message = String(error);\n\tconst exportsRejected = /Package subpath .* is not defined by "exports"/.test(message);\n\tconst bunRejected = (message.startsWith("ResolveMessage: Cannot find module '" + privateSubpath + "' from '") && message.endsWith("/probe.ts'")) || (message.startsWith("ResolveMessage: Cannot find package '" + ${JSON.stringify(packageName)} + "' imported from ") && message.endsWith("/probe.ts"));\n\tif (!exportsRejected && !bunRejected) throw new Error("private managed-session scope failed for an unexpected reason: " + message);\n}\nprocess.stdout.write(JSON.stringify({ root: Object.keys(root).sort(), sdk: Object.keys(sdk).sort() }));\n`,
|
|
154
156
|
);
|
|
155
157
|
await fs.appendFile(
|
|
156
158
|
probePath,
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import * as fs from "node:fs/promises";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { RETIRED_MODEL_KEYS } from "../../ai/src/model-retirements";
|
|
6
|
+
import { isValidAutoroutingSelector } from "../src/config/autorouting-contract";
|
|
7
|
+
import {
|
|
8
|
+
CURATED_TIER_LABELS,
|
|
9
|
+
type CuratedTierLabels,
|
|
10
|
+
TIER_MAP_SKIP_LIST,
|
|
11
|
+
type TierMapSkipList,
|
|
12
|
+
} from "../src/config/autorouting-tier-map";
|
|
13
|
+
|
|
14
|
+
export const BASELINE_SKIP_RATIONALE = "pre-feature baseline; not yet curated";
|
|
15
|
+
const DISCOVERY_ONLY_PROVIDERS = new Set(["ollama", "vllm"]);
|
|
16
|
+
const RETIRED_KEYS = new Set<string>(RETIRED_MODEL_KEYS);
|
|
17
|
+
|
|
18
|
+
export type CommittedCatalogModel = {
|
|
19
|
+
id?: unknown;
|
|
20
|
+
provider?: unknown;
|
|
21
|
+
output?: unknown;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type CommittedCatalog = Record<string, Record<string, CommittedCatalogModel>>;
|
|
26
|
+
|
|
27
|
+
export type AutoroutingTierMapGateReport = {
|
|
28
|
+
inScopeKeys: string[];
|
|
29
|
+
labeledKeys: string[];
|
|
30
|
+
skippedKeys: string[];
|
|
31
|
+
unlabeledKeys: string[];
|
|
32
|
+
invalidLabelKeys: string[];
|
|
33
|
+
outOfScopeLabelKeys: string[];
|
|
34
|
+
invalidSkipKeys: string[];
|
|
35
|
+
staleSkipKeys: string[];
|
|
36
|
+
baselineSkipCount: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function modelKey(provider: string, id: string): string {
|
|
40
|
+
return `${provider}/${id}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isImageGenerationOnly(model: CommittedCatalogModel): boolean {
|
|
44
|
+
return Array.isArray(model.output) && model.output.length > 0 && model.output.every(output => output === "image");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function isInAutoroutingGateScope(provider: string, id: string, model: CommittedCatalogModel): boolean {
|
|
48
|
+
const key = modelKey(provider, id);
|
|
49
|
+
return (
|
|
50
|
+
isValidAutoroutingSelector(key) &&
|
|
51
|
+
!RETIRED_KEYS.has(key) &&
|
|
52
|
+
!DISCOVERY_ONLY_PROVIDERS.has(provider) &&
|
|
53
|
+
!isImageGenerationOnly(model)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function committedCatalogKeys(catalog: CommittedCatalog): string[] {
|
|
58
|
+
const keys: string[] = [];
|
|
59
|
+
for (const [provider, models] of Object.entries(catalog)) {
|
|
60
|
+
if (models === null || typeof models !== "object" || Array.isArray(models)) continue;
|
|
61
|
+
for (const [id, model] of Object.entries(models)) {
|
|
62
|
+
if (isInAutoroutingGateScope(provider, id, model)) keys.push(modelKey(provider, id));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return keys.sort((left, right) => left.localeCompare(right));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function getAutoroutingTierMapGateReport(
|
|
69
|
+
catalog: CommittedCatalog,
|
|
70
|
+
labels: CuratedTierLabels = CURATED_TIER_LABELS,
|
|
71
|
+
skips: TierMapSkipList = TIER_MAP_SKIP_LIST,
|
|
72
|
+
): AutoroutingTierMapGateReport {
|
|
73
|
+
const catalogKeys = new Set(committedCatalogKeys(catalog));
|
|
74
|
+
const labeledKeys = Object.keys(labels).sort((left, right) => left.localeCompare(right));
|
|
75
|
+
const skippedKeys = Object.keys(skips).sort((left, right) => left.localeCompare(right));
|
|
76
|
+
const invalidLabelKeys = labeledKeys.filter(key => !catalogKeys.has(key));
|
|
77
|
+
const outOfScopeLabelKeys = labeledKeys.filter(key => {
|
|
78
|
+
const separator = key.indexOf("/");
|
|
79
|
+
const provider = separator > 0 ? key.slice(0, separator) : key;
|
|
80
|
+
const id = separator > 0 ? key.slice(separator + 1) : "";
|
|
81
|
+
const rawModel = catalog[provider]?.[id];
|
|
82
|
+
return rawModel !== undefined && !isInAutoroutingGateScope(provider, id, rawModel);
|
|
83
|
+
});
|
|
84
|
+
const unlabeledKeys = [...catalogKeys].filter(key => !Object.hasOwn(labels, key) && !Object.hasOwn(skips, key));
|
|
85
|
+
const inScopeKeys = [...catalogKeys];
|
|
86
|
+
const inScopeSkipped = skippedKeys.filter(key => catalogKeys.has(key));
|
|
87
|
+
const invalidSkipKeys = skippedKeys.filter(key => {
|
|
88
|
+
const entry = (skips as Record<string, { rationale?: unknown }>)[key];
|
|
89
|
+
const rationale = entry?.rationale;
|
|
90
|
+
return typeof rationale !== "string" || rationale.trim().length === 0 || !isValidAutoroutingSelector(key);
|
|
91
|
+
});
|
|
92
|
+
const staleSkipKeys = skippedKeys.filter(key => !catalogKeys.has(key) && !invalidSkipKeys.includes(key));
|
|
93
|
+
// A key that is both labeled and skipped would let a curated tier assignment hide
|
|
94
|
+
// behind a skip rationale; it is an invalid skip, not a stale one.
|
|
95
|
+
const bothLabeledAndSkipped = skippedKeys.filter(key => Object.hasOwn(labels, key));
|
|
96
|
+
invalidSkipKeys.push(...bothLabeledAndSkipped.filter(key => !invalidSkipKeys.includes(key)));
|
|
97
|
+
return {
|
|
98
|
+
inScopeKeys,
|
|
99
|
+
labeledKeys,
|
|
100
|
+
skippedKeys: inScopeSkipped,
|
|
101
|
+
unlabeledKeys: unlabeledKeys.sort((left, right) => left.localeCompare(right)),
|
|
102
|
+
invalidLabelKeys,
|
|
103
|
+
outOfScopeLabelKeys,
|
|
104
|
+
invalidSkipKeys,
|
|
105
|
+
staleSkipKeys,
|
|
106
|
+
baselineSkipCount: inScopeSkipped.filter(
|
|
107
|
+
key => (skips as Record<string, { baseline?: true }>)[key]?.baseline === true,
|
|
108
|
+
).length,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function findUnlabeledAutoroutingKeys(
|
|
113
|
+
catalog: CommittedCatalog,
|
|
114
|
+
labels: CuratedTierLabels = CURATED_TIER_LABELS,
|
|
115
|
+
skips: TierMapSkipList = TIER_MAP_SKIP_LIST,
|
|
116
|
+
): string[] {
|
|
117
|
+
return getAutoroutingTierMapGateReport(catalog, labels, skips).unlabeledKeys;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export type AutoroutingTierMapGateResult = {
|
|
121
|
+
ok: boolean;
|
|
122
|
+
report: AutoroutingTierMapGateReport;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export function checkAutoroutingTierMap(
|
|
126
|
+
catalog: CommittedCatalog,
|
|
127
|
+
labels: CuratedTierLabels = CURATED_TIER_LABELS,
|
|
128
|
+
skips: TierMapSkipList = TIER_MAP_SKIP_LIST,
|
|
129
|
+
): AutoroutingTierMapGateResult {
|
|
130
|
+
const report = getAutoroutingTierMapGateReport(catalog, labels, skips);
|
|
131
|
+
const ok =
|
|
132
|
+
report.unlabeledKeys.length === 0 &&
|
|
133
|
+
report.invalidLabelKeys.length === 0 &&
|
|
134
|
+
report.outOfScopeLabelKeys.length === 0 &&
|
|
135
|
+
report.invalidSkipKeys.length === 0 &&
|
|
136
|
+
report.staleSkipKeys.length === 0;
|
|
137
|
+
return { ok, report };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function loadCommittedCatalog(
|
|
141
|
+
repoRoot = path.resolve(import.meta.dir, "../../.."),
|
|
142
|
+
): Promise<CommittedCatalog> {
|
|
143
|
+
const catalogPath = path.join(repoRoot, "packages/ai/src/models.json");
|
|
144
|
+
return JSON.parse(await fs.readFile(catalogPath, "utf8")) as CommittedCatalog;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function runAutoroutingTierMapGate(repoRoot?: string): Promise<AutoroutingTierMapGateResult> {
|
|
148
|
+
return checkAutoroutingTierMap(await loadCommittedCatalog(repoRoot));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const checkTierMap = checkAutoroutingTierMap;
|
|
152
|
+
export const findUnlabeledKeys = findUnlabeledAutoroutingKeys;
|
|
153
|
+
export const runTierMapGate = runAutoroutingTierMapGate;
|
|
154
|
+
|
|
155
|
+
function printFailure(report: AutoroutingTierMapGateReport): void {
|
|
156
|
+
const failures = [
|
|
157
|
+
...new Set([
|
|
158
|
+
...report.unlabeledKeys,
|
|
159
|
+
...report.invalidLabelKeys,
|
|
160
|
+
...report.outOfScopeLabelKeys,
|
|
161
|
+
...report.invalidSkipKeys,
|
|
162
|
+
...report.staleSkipKeys,
|
|
163
|
+
]),
|
|
164
|
+
].sort((a, b) => a.localeCompare(b));
|
|
165
|
+
console.error("Autorouting tier-map gate failed.");
|
|
166
|
+
console.error("Offending provider/model-id keys:");
|
|
167
|
+
for (const key of failures) console.error(`- ${key}`);
|
|
168
|
+
console.error(
|
|
169
|
+
"Add each new key to CURATED_TIER_LABELS with reviewed tier/rank data, or add it to TIER_MAP_SKIP_LIST with a non-empty rationale; remove skip entries whose key left the catalog or the selector grammar.",
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (import.meta.main) {
|
|
174
|
+
const result = await runAutoroutingTierMapGate();
|
|
175
|
+
if (!result.ok) {
|
|
176
|
+
printFailure(result.report);
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
} else {
|
|
179
|
+
console.log(
|
|
180
|
+
`Autorouting tier-map gate passed: ${result.report.inScopeKeys.length} in-scope keys; ${result.report.baselineSkipCount} baseline skips.`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -17,6 +17,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
17
17
|
"internal terminal-abort bus seam, threaded via terminalAbortSeams; not a user-facing SDK control seam",
|
|
18
18
|
"agent_session:abortPromptAndWaitWithTerminal":
|
|
19
19
|
"internal terminal-abort fencing seam, threaded via terminalAbortSeams; not a user-facing SDK control seam",
|
|
20
|
+
"slash_command:routing":
|
|
21
|
+
"visual/local-only autorouting settings toggle and smart-routing panel entry, not a user-facing SDK control seam",
|
|
20
22
|
"slash_command:settings": "visual/local-only command, not a user-facing SDK control seam",
|
|
21
23
|
"slash_command:theme": "visual/local-only command, not a user-facing SDK control seam",
|
|
22
24
|
"slash_command:copy": "visual/local-only command, not a user-facing SDK control seam",
|
|
@@ -73,6 +75,16 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
73
75
|
"agent_session:setForcedToolChoice": "internal accessor/plumbing, not a user-facing control seam",
|
|
74
76
|
"agent_session:getActiveSkillState": "internal accessor/plumbing, not a user-facing control seam",
|
|
75
77
|
"agent_session:getActiveSkillPhase": "internal accessor/plumbing, not a user-facing control seam",
|
|
78
|
+
"agent_session:getEffectiveActiveWorkflowSkillState":
|
|
79
|
+
"internal restored-or-live workflow guard for session rescope, not a user-facing SDK control seam",
|
|
80
|
+
"agent_session:replaceOwnedMcpManager":
|
|
81
|
+
"internal cwd-rebinding helper for owned MCP authority after move_session, not a user-facing SDK control seam",
|
|
82
|
+
"agent_session:replaceNamedCustomTools":
|
|
83
|
+
"internal cwd-rebinding helper for named custom tools after move_session, not a user-facing SDK control seam",
|
|
84
|
+
"agent_session:replaceSkills":
|
|
85
|
+
"internal cwd-rebinding helper for session skills after move_session, not a user-facing SDK control seam",
|
|
86
|
+
"agent_session:retireWorkspaceTreeForRescope":
|
|
87
|
+
"internal cwd-rebinding helper that retires the cached workspace tree after move_session, not a user-facing SDK control seam",
|
|
76
88
|
"agent_session:getDeepInterviewAskStage":
|
|
77
89
|
"internal AskTool schema-selection accessor, not a user-facing SDK control seam",
|
|
78
90
|
"agent_session:peekQueueInvoker": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as os from "node:os";
|
|
1
3
|
import * as path from "node:path";
|
|
2
4
|
import { toolWireSchema } from "@gajae-code/ai/utils/schema";
|
|
3
5
|
import { TaskTool } from "../src/task";
|
|
@@ -80,7 +82,8 @@ function makeSettings() {
|
|
|
80
82
|
"task.isolation.mode": "none",
|
|
81
83
|
"task.simpleMode": "off",
|
|
82
84
|
"task.simple": "default",
|
|
83
|
-
"task.parentSpawns": "
|
|
85
|
+
"task.parentSpawns": "executor,architect,planner,critic",
|
|
86
|
+
"task.allowedAgents": ["executor", "architect", "planner", "critic"],
|
|
84
87
|
disabledExtensions: [],
|
|
85
88
|
"memory.backend": "off",
|
|
86
89
|
"edit.fuzzyMatch": true,
|
|
@@ -94,14 +97,16 @@ function makeSettings() {
|
|
|
94
97
|
getGroup: (group: string) => {
|
|
95
98
|
if (group === "skills")
|
|
96
99
|
return { enabled: true, enablePiUser: true, enablePiProject: true, customDirectories: [] };
|
|
97
|
-
if (group === "task") return { disabledAgents: [] };
|
|
100
|
+
if (group === "task") return { disabledAgents: [], agents: [], allowedAgents: values["task.allowedAgents"] };
|
|
98
101
|
return {};
|
|
99
102
|
},
|
|
100
103
|
getNotificationSettingsSnapshot: () => ({ enabled: false, telegram: {}, discord: {}, slack: {} }),
|
|
104
|
+
// The catalog documents the default configuration, where autorouting is off.
|
|
105
|
+
getEffectiveAutorouting: () => ({ active: false }),
|
|
101
106
|
};
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
function makeSession(cwd: string
|
|
109
|
+
function makeSession(cwd: string): any {
|
|
105
110
|
const settings = makeSettings();
|
|
106
111
|
return {
|
|
107
112
|
cwd,
|
|
@@ -113,6 +118,7 @@ function makeSession(cwd: string = path.resolve(import.meta.dir, "../..")): any
|
|
|
113
118
|
hasEditTool: true,
|
|
114
119
|
taskDepth: 0,
|
|
115
120
|
currentAgentType: "executor",
|
|
121
|
+
rescopeSessionCwd: async () => ({ from: cwd, to: cwd }),
|
|
116
122
|
getSessionFile: () => null,
|
|
117
123
|
getSessionSpawns: () => null,
|
|
118
124
|
getSessionId: () => "catalog",
|
|
@@ -316,7 +322,21 @@ export async function generateToolCatalogData(
|
|
|
316
322
|
options: ToolCatalogGenerationOptions = {},
|
|
317
323
|
): Promise<Record<string, GeneratedToolCatalogEntry>> {
|
|
318
324
|
const previousEditVariant = process.env.GJC_EDIT_VARIANT;
|
|
325
|
+
const previousHome = process.env.HOME;
|
|
326
|
+
const previousGjcConfigDir = process.env.GJC_CONFIG_DIR;
|
|
327
|
+
const previousPiConfigDir = process.env.PI_CONFIG_DIR;
|
|
328
|
+
const previousGjcCodingAgentDir = process.env.GJC_CODING_AGENT_DIR;
|
|
329
|
+
const previousPiCodingAgentDir = process.env.PI_CODING_AGENT_DIR;
|
|
330
|
+
const isolatedRoot = await fs.mkdtemp(path.join(os.tmpdir(), "gjc-tool-catalog-"));
|
|
331
|
+
const gitInit = Bun.spawnSync(["git", "init", "--quiet", isolatedRoot]);
|
|
332
|
+
if (gitInit.exitCode !== 0)
|
|
333
|
+
throw new Error(`Failed to initialize isolated tool-catalog repository: ${gitInit.stderr}`);
|
|
319
334
|
process.env.GJC_EDIT_VARIANT = "replace";
|
|
335
|
+
process.env.HOME = path.join(isolatedRoot, "home");
|
|
336
|
+
process.env.GJC_CONFIG_DIR = ".gjc-catalog";
|
|
337
|
+
process.env.PI_CONFIG_DIR = ".gjc-catalog";
|
|
338
|
+
process.env.GJC_CODING_AGENT_DIR = path.join(isolatedRoot, "agent");
|
|
339
|
+
process.env.PI_CODING_AGENT_DIR = path.join(isolatedRoot, "agent");
|
|
320
340
|
const platform = options.platform ?? process.platform;
|
|
321
341
|
const arch = options.arch ?? process.arch;
|
|
322
342
|
try {
|
|
@@ -328,7 +348,7 @@ export async function generateToolCatalogData(
|
|
|
328
348
|
...HIDDEN_TOOL_DESCRIPTORS,
|
|
329
349
|
...PLATFORM_EXCLUDED_TOOL_DESCRIPTORS,
|
|
330
350
|
} as Record<string, any>;
|
|
331
|
-
const session = makeSession(
|
|
351
|
+
const session = makeSession(isolatedRoot);
|
|
332
352
|
const output: Record<string, GeneratedToolCatalogEntry> = {};
|
|
333
353
|
for (const [name, descriptor] of Object.entries(all)) {
|
|
334
354
|
let fallback: AuditedFallback | undefined;
|
|
@@ -432,10 +452,14 @@ export async function generateToolCatalogData(
|
|
|
432
452
|
const choose = <T>(key: string, descriptorValue: T | undefined): T | undefined =>
|
|
433
453
|
fallback ? (read(key) as T | undefined) : ((read(key) as T | undefined) ?? descriptorValue);
|
|
434
454
|
const intent = choose("intent", descriptor.metadata.intent);
|
|
455
|
+
const description = choose("description", descriptor.metadata.description);
|
|
435
456
|
const entry: GeneratedToolCatalogEntry = {
|
|
436
457
|
name,
|
|
437
458
|
label: choose("label", descriptor.presentation.label),
|
|
438
|
-
description:
|
|
459
|
+
description:
|
|
460
|
+
name === "task" && typeof description === "string"
|
|
461
|
+
? description.replace(/\n# reviewer\n[^\n]*\n\n/g, "")
|
|
462
|
+
: description,
|
|
439
463
|
parameters: serializeCatalogValue(name, "parameters", parameters) as Record<string, unknown>,
|
|
440
464
|
strict: choose("strict", descriptor.metadata.strict),
|
|
441
465
|
hidden: choose("hidden", descriptor.metadata.hidden),
|
|
@@ -465,6 +489,17 @@ export async function generateToolCatalogData(
|
|
|
465
489
|
} finally {
|
|
466
490
|
if (previousEditVariant === undefined) delete process.env.GJC_EDIT_VARIANT;
|
|
467
491
|
else process.env.GJC_EDIT_VARIANT = previousEditVariant;
|
|
492
|
+
if (previousHome === undefined) delete process.env.HOME;
|
|
493
|
+
else process.env.HOME = previousHome;
|
|
494
|
+
if (previousGjcConfigDir === undefined) delete process.env.GJC_CONFIG_DIR;
|
|
495
|
+
else process.env.GJC_CONFIG_DIR = previousGjcConfigDir;
|
|
496
|
+
if (previousPiConfigDir === undefined) delete process.env.PI_CONFIG_DIR;
|
|
497
|
+
else process.env.PI_CONFIG_DIR = previousPiConfigDir;
|
|
498
|
+
if (previousGjcCodingAgentDir === undefined) delete process.env.GJC_CODING_AGENT_DIR;
|
|
499
|
+
else process.env.GJC_CODING_AGENT_DIR = previousGjcCodingAgentDir;
|
|
500
|
+
if (previousPiCodingAgentDir === undefined) delete process.env.PI_CODING_AGENT_DIR;
|
|
501
|
+
else process.env.PI_CODING_AGENT_DIR = previousPiCodingAgentDir;
|
|
502
|
+
await fs.rm(isolatedRoot, { recursive: true, force: true });
|
|
468
503
|
}
|
|
469
504
|
}
|
|
470
505
|
|
package/src/async/job-manager.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
retireOwnedRegistrationForDeadLetter,
|
|
7
7
|
unregisterOwnedRegistration,
|
|
8
8
|
} from "../session/terminal-abort";
|
|
9
|
-
import type { AgentProgress, AgentSource } from "../task/types";
|
|
9
|
+
import type { AgentProgress, AgentSource, LocalErrorSummary } from "../task/types";
|
|
10
10
|
|
|
11
11
|
const DELIVERY_RETRY_BASE_MS = 500;
|
|
12
12
|
const DELIVERY_RETRY_MAX_MS = 30_000;
|
|
@@ -42,6 +42,8 @@ export interface AsyncJob {
|
|
|
42
42
|
errorText?: string;
|
|
43
43
|
/** Safe, bounded cause when session setup failed before the LLM began work. */
|
|
44
44
|
setupFailureSummary?: string;
|
|
45
|
+
/** Safe, bounded summary of a terminal local (non-provider) failure kind. */
|
|
46
|
+
localErrorSummary?: LocalErrorSummary;
|
|
45
47
|
metadata?: AsyncJobMetadata;
|
|
46
48
|
/**
|
|
47
49
|
* Registry id of the agent that registered the job (e.g. "0-Main",
|
|
@@ -85,7 +87,7 @@ export interface AsyncJobMetadata {
|
|
|
85
87
|
*/
|
|
86
88
|
export type SubagentRunOutcome =
|
|
87
89
|
| { kind: "completed"; text: string }
|
|
88
|
-
| { kind: "failed"; text: string; setupFailureSummary?: string }
|
|
90
|
+
| { kind: "failed"; text: string; setupFailureSummary?: string; localErrorSummary?: LocalErrorSummary }
|
|
89
91
|
| { kind: "paused"; note?: string };
|
|
90
92
|
|
|
91
93
|
/** Canonical lifecycle of a subagent across pause/resume cycles. */
|
|
@@ -985,6 +987,7 @@ export class AsyncJobManager {
|
|
|
985
987
|
if (outcome.kind === "failed") {
|
|
986
988
|
job.status = "failed";
|
|
987
989
|
job.setupFailureSummary = outcome.setupFailureSummary;
|
|
990
|
+
job.localErrorSummary = outcome.localErrorSummary;
|
|
988
991
|
this.#freezeEndTime(job);
|
|
989
992
|
job.errorText = outcome.text;
|
|
990
993
|
this.#markRecordTerminal(id, "failed", job.generation);
|