@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
package/src/tools/subagent.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { formatDuration, logger, prompt } from "@gajae-code/utils";
|
|
|
4
4
|
import * as z from "zod/v4";
|
|
5
5
|
import { type AsyncJob, AsyncJobManager, jobElapsedMs, type SubagentRecord } from "../async";
|
|
6
6
|
import subagentDescription from "../prompts/tools/subagent.md" with { type: "text" };
|
|
7
|
-
import type { AgentProgress, AgentSource,
|
|
7
|
+
import type { AgentProgress, AgentSource, LocalErrorSummary } from "../task/types";
|
|
8
8
|
import { Ellipsis, truncateToWidth } from "../tui";
|
|
9
9
|
import type { ToolSession } from "./index";
|
|
10
10
|
import { replaceTabs } from "./render-utils";
|
|
@@ -85,6 +85,8 @@ export interface SubagentSnapshot {
|
|
|
85
85
|
errorText?: string;
|
|
86
86
|
/** Safe setup failure cause retained from the executor launch path. */
|
|
87
87
|
setupFailureSummary?: string;
|
|
88
|
+
/** Safe, bounded summary of a terminal local (non-provider) failure (e.g. local_buffer_overflow). */
|
|
89
|
+
localErrorSummary?: LocalErrorSummary;
|
|
88
90
|
resultPreview?: string;
|
|
89
91
|
outputRef?: string;
|
|
90
92
|
truncated?: boolean;
|
|
@@ -92,8 +94,8 @@ export interface SubagentSnapshot {
|
|
|
92
94
|
steerMessage?: string;
|
|
93
95
|
steerState?: "queued" | "resume_queued" | "resume_started";
|
|
94
96
|
steerPauseRequested?: boolean;
|
|
95
|
-
/**
|
|
96
|
-
progress?:
|
|
97
|
+
/** Bounded live progress approved for the await panel and public tool details. */
|
|
98
|
+
progress?: SubagentLiveProgress;
|
|
97
99
|
/** True when a live in-session progress producer exists for this subagent. */
|
|
98
100
|
liveProgressAvailable?: boolean;
|
|
99
101
|
/** Model the subagent actually runs on (after any auth fallback). */
|
|
@@ -106,6 +108,63 @@ export interface SubagentSnapshot {
|
|
|
106
108
|
fastMode?: boolean;
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Public await-panel progress. This is deliberately not `AgentProgress`: raw
|
|
113
|
+
* progress contains model deltas, tool arguments, arbitrary output, and nested
|
|
114
|
+
* task payloads that must never enter tool-result, ACP, or telemetry envelopes.
|
|
115
|
+
*/
|
|
116
|
+
export interface SubagentLiveProgress {
|
|
117
|
+
id: string;
|
|
118
|
+
status: AgentProgress["status"];
|
|
119
|
+
currentTool?: string;
|
|
120
|
+
recentTool?: string;
|
|
121
|
+
recentOutputSummary?: { lineCount: number };
|
|
122
|
+
fastMode?: boolean;
|
|
123
|
+
retryState?: {
|
|
124
|
+
attempt: number;
|
|
125
|
+
maxAttempts: number;
|
|
126
|
+
unbounded?: boolean;
|
|
127
|
+
kind: NonNullable<AgentProgress["retryState"]>["kind"];
|
|
128
|
+
provider?: string;
|
|
129
|
+
lastProviderProgressAtMs?: number;
|
|
130
|
+
delayMs: number;
|
|
131
|
+
startedAtMs: number;
|
|
132
|
+
};
|
|
133
|
+
retryFailure?: { attempt: number };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function toSubagentLiveProgress(progress: AgentProgress): SubagentLiveProgress {
|
|
137
|
+
return {
|
|
138
|
+
id: progress.id,
|
|
139
|
+
status: progress.status,
|
|
140
|
+
...(progress.currentTool ? { currentTool: progress.currentTool } : {}),
|
|
141
|
+
...(progress.currentTool === undefined && progress.recentTools[0]
|
|
142
|
+
? { recentTool: progress.recentTools[0].tool }
|
|
143
|
+
: {}),
|
|
144
|
+
...(progress.recentOutput.length > 0
|
|
145
|
+
? { recentOutputSummary: { lineCount: Math.min(progress.recentOutput.length, 6) } }
|
|
146
|
+
: {}),
|
|
147
|
+
...(progress.fastMode ? { fastMode: true } : {}),
|
|
148
|
+
...(progress.retryState
|
|
149
|
+
? {
|
|
150
|
+
retryState: {
|
|
151
|
+
attempt: progress.retryState.attempt,
|
|
152
|
+
maxAttempts: progress.retryState.maxAttempts,
|
|
153
|
+
...(progress.retryState.unbounded ? { unbounded: true } : {}),
|
|
154
|
+
kind: progress.retryState.kind,
|
|
155
|
+
...(progress.retryState.provider ? { provider: progress.retryState.provider } : {}),
|
|
156
|
+
...(progress.retryState.lastProviderProgressAtMs !== undefined
|
|
157
|
+
? { lastProviderProgressAtMs: progress.retryState.lastProviderProgressAtMs }
|
|
158
|
+
: {}),
|
|
159
|
+
delayMs: progress.retryState.delayMs,
|
|
160
|
+
startedAtMs: progress.retryState.startedAtMs,
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
: {}),
|
|
164
|
+
...(progress.retryFailure ? { retryFailure: { attempt: progress.retryFailure.attempt } } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
109
168
|
export type SubagentAwaitOutcome = "completed" | "timed_out" | "interrupted";
|
|
110
169
|
|
|
111
170
|
const AWAIT_INTERRUPTED_GUIDANCE =
|
|
@@ -723,6 +782,22 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
723
782
|
if (snapshot.description) lines.push(`Description: ${snapshot.description}`);
|
|
724
783
|
if (snapshot.outputRef) lines.push(`Output: ${snapshot.outputRef}`);
|
|
725
784
|
if (snapshot.setupFailureSummary) lines.push(`Setup failure: ${snapshot.setupFailureSummary}`);
|
|
785
|
+
if (snapshot.localErrorSummary) {
|
|
786
|
+
const local = snapshot.localErrorSummary;
|
|
787
|
+
lines.push(`Local failure (${local.kind}): ${local.summary}`);
|
|
788
|
+
// Guidance is kind-conditional: an overflow is a local staging
|
|
789
|
+
// limit that reproduces on re-issue; a snapshot failure is a
|
|
790
|
+
// serialization defect, which re-issuing does NOT reproduce.
|
|
791
|
+
if (local.kind === "local_buffer_overflow") {
|
|
792
|
+
lines.push(
|
|
793
|
+
"This is a local gjc staging-buffer limit, not a provider or context-window failure; the same request reproduces it.",
|
|
794
|
+
);
|
|
795
|
+
} else if (local.kind === "local_snapshot_failure") {
|
|
796
|
+
lines.push(
|
|
797
|
+
"This is a local gjc event-serialization defect, not a provider failure; re-issuing is safe to retry.",
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
726
801
|
if (snapshot.assignment) lines.push("Assignment:", "```", snapshot.assignment, "```");
|
|
727
802
|
if (snapshot.steerMessage) {
|
|
728
803
|
lines.push(`Steer (${snapshot.steerState ?? "queued"}):`, "```", snapshot.steerMessage, "```");
|
|
@@ -770,7 +845,7 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
770
845
|
const progress = manager.getSubagentProgress(record.subagentId);
|
|
771
846
|
return {
|
|
772
847
|
liveProgressAvailable: true,
|
|
773
|
-
...(progress ? { progress } : {}),
|
|
848
|
+
...(progress ? { progress: toSubagentLiveProgress(progress) } : {}),
|
|
774
849
|
};
|
|
775
850
|
}
|
|
776
851
|
|
|
@@ -853,6 +928,14 @@ export class SubagentTool implements AgentTool<typeof subagentSchema, SubagentTo
|
|
|
853
928
|
...(job.setupFailureSummary
|
|
854
929
|
? { setupFailureSummary: sanitizeText(job.setupFailureSummary, RECEIPT_PREVIEW_WIDTH) }
|
|
855
930
|
: {}),
|
|
931
|
+
...(job.localErrorSummary
|
|
932
|
+
? {
|
|
933
|
+
localErrorSummary: {
|
|
934
|
+
kind: job.localErrorSummary.kind,
|
|
935
|
+
summary: sanitizeText(job.localErrorSummary.summary, RECEIPT_PREVIEW_WIDTH),
|
|
936
|
+
},
|
|
937
|
+
}
|
|
938
|
+
: {}),
|
|
856
939
|
...(outputRef ? { outputRef } : {}),
|
|
857
940
|
...(runningTimeoutGuidance ? { guidance: runningTimeoutGuidance } : {}),
|
|
858
941
|
...this.#modelFields(record),
|
|
@@ -1063,36 +1146,15 @@ function canonicalizeSnapshotForSignature(snapshot: SubagentSnapshot): unknown {
|
|
|
1063
1146
|
};
|
|
1064
1147
|
}
|
|
1065
1148
|
|
|
1066
|
-
function canonicalizeProgressForSignature(progress:
|
|
1149
|
+
function canonicalizeProgressForSignature(progress: SubagentLiveProgress): unknown {
|
|
1067
1150
|
return {
|
|
1068
1151
|
id: progress.id,
|
|
1069
|
-
agent: progress.agent,
|
|
1070
|
-
agentSource: progress.agentSource,
|
|
1071
1152
|
status: progress.status,
|
|
1072
|
-
task: progress.task,
|
|
1073
|
-
assignment: progress.assignment ?? null,
|
|
1074
|
-
description: progress.description ?? null,
|
|
1075
|
-
lastIntent: progress.lastIntent ?? null,
|
|
1076
1153
|
currentTool: progress.currentTool ?? null,
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
recentTools: progress.recentTools.map(tool => ({ tool: tool.tool, args: tool.args })),
|
|
1080
|
-
recentOutput: progress.recentOutput,
|
|
1081
|
-
toolCount: progress.toolCount,
|
|
1082
|
-
tokens: progress.tokens,
|
|
1083
|
-
contextTokens: progress.contextTokens ?? null,
|
|
1084
|
-
contextWindow: progress.contextWindow ?? null,
|
|
1085
|
-
cost: progress.cost,
|
|
1086
|
-
modelOverride: progress.modelOverride ?? null,
|
|
1087
|
-
modelSubstitutionWarning: progress.modelSubstitutionWarning ?? null,
|
|
1088
|
-
// The nested task panel renders this, so it must reach the signature or a
|
|
1089
|
-
// fast-mode-only change would render differently while comparing byte-identical,
|
|
1090
|
-
// suppressing the very update that introduces the glyph.
|
|
1154
|
+
recentTool: progress.recentTool ?? null,
|
|
1155
|
+
recentOutputSummary: progress.recentOutputSummary ?? null,
|
|
1091
1156
|
fastMode: progress.fastMode ?? false,
|
|
1092
|
-
|
|
1093
|
-
extractedToolData: progress.extractedToolData
|
|
1094
|
-
? canonicalizeExtractedToolDataForSignature(progress.extractedToolData)
|
|
1095
|
-
: null,
|
|
1157
|
+
retryFailure: progress.retryFailure ?? null,
|
|
1096
1158
|
retryState: progress.retryState
|
|
1097
1159
|
? {
|
|
1098
1160
|
attempt: progress.retryState.attempt,
|
|
@@ -1101,52 +1163,7 @@ function canonicalizeProgressForSignature(progress: AgentProgress): unknown {
|
|
|
1101
1163
|
kind: progress.retryState.kind,
|
|
1102
1164
|
provider: progress.retryState.provider ?? null,
|
|
1103
1165
|
delayMs: progress.retryState.delayMs,
|
|
1104
|
-
errorMessage: progress.retryState.errorMessage,
|
|
1105
|
-
// startedAtMs intentionally excluded (drives countdown only).
|
|
1106
1166
|
}
|
|
1107
1167
|
: null,
|
|
1108
|
-
retryFailure: progress.retryFailure ?? null,
|
|
1109
|
-
inflightTaskDetails: progress.inflightTaskDetails
|
|
1110
|
-
? canonicalizeTaskDetailsForSignature(progress.inflightTaskDetails)
|
|
1111
|
-
: null,
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
/**
|
|
1116
|
-
* Nested `task` data (`extractedToolData.task` and `inflightTaskDetails`) is the
|
|
1117
|
-
* one place the await signature reaches into a live, ticking structure: nested
|
|
1118
|
-
* `AgentProgress` carries the same time-derived fields excluded above, and
|
|
1119
|
-
* `TaskToolDetails` adds `totalDurationMs` / per-result `durationMs`. Signing it
|
|
1120
|
-
* wholesale would defeat idle gating whenever an awaited subagent is itself inside
|
|
1121
|
-
* a live `task` call, so these helpers canonicalize the rendered, non-time subset
|
|
1122
|
-
* recursively (mutually recursive with `canonicalizeProgressForSignature`).
|
|
1123
|
-
*/
|
|
1124
|
-
function canonicalizeExtractedToolDataForSignature(data: Record<string, unknown[]>): Record<string, unknown> {
|
|
1125
|
-
const out: Record<string, unknown> = {};
|
|
1126
|
-
for (const key of Object.keys(data)) {
|
|
1127
|
-
// Only the `task` key holds time-ticking `TaskToolDetails`; other handler
|
|
1128
|
-
// data (yield/report_finding/generic) is stable and passes through as-is.
|
|
1129
|
-
out[key] = key === "task" ? (data[key] as TaskToolDetails[]).map(canonicalizeTaskDetailsForSignature) : data[key];
|
|
1130
|
-
}
|
|
1131
|
-
return out;
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
function canonicalizeTaskDetailsForSignature(details: TaskToolDetails): unknown {
|
|
1135
|
-
// `extractedToolData` is an untyped boundary (`Record<string, unknown[]>`), so
|
|
1136
|
-
// guard each field instead of trusting the `TaskToolDetails` cast.
|
|
1137
|
-
return {
|
|
1138
|
-
// totalDurationMs intentionally excluded (time-derived).
|
|
1139
|
-
results: Array.isArray(details.results) ? details.results.map(canonicalizeTaskResultForSignature) : null,
|
|
1140
|
-
progress: Array.isArray(details.progress) ? details.progress.map(canonicalizeProgressForSignature) : null,
|
|
1141
|
-
async: details.async
|
|
1142
|
-
? { state: details.async.state, jobId: details.async.jobId, type: details.async.type }
|
|
1143
|
-
: null,
|
|
1144
1168
|
};
|
|
1145
1169
|
}
|
|
1146
|
-
|
|
1147
|
-
function canonicalizeTaskResultForSignature(result: TaskToolDetails["results"][number]): unknown {
|
|
1148
|
-
// Completed results do not tick, but drop `durationMs` so the only time-derived
|
|
1149
|
-
// field in the receipt can never reintroduce idle churn.
|
|
1150
|
-
const { durationMs: _durationMs, ...rest } = result;
|
|
1151
|
-
return rest;
|
|
1152
|
-
}
|
|
@@ -681,6 +681,35 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
681
681
|
"summary": "Execute Python or JavaScript code in an in-process eval backend",
|
|
682
682
|
"concurrency": "exclusive"
|
|
683
683
|
},
|
|
684
|
+
"python": {
|
|
685
|
+
"name": "python",
|
|
686
|
+
"label": "Python",
|
|
687
|
+
"description": "Execute Python in a persistent per-session REPL kernel.\n\nVariables, imports, and loaded data persist across calls in the current GJC session. The kernel runs in the session working directory. Each `execute` call is appended to a JSONL transcript under `.gjc/_session-{sessionid}/ipykernels/`; display artifacts are stored under `.gjc/_session-{sessionid}/ipykernels/artifacts/`.\n\n## Actions\n\n- `execute` (default) — run `code` in the persistent REPL. Requires `code`.\n- `clear` — dispose this session's Python kernel. The next `execute` starts a fresh kernel with no retained state.\n\n## Use\n\nUse this tool for stateful Python work. It is distinct from `eval`: each has a separate kernel and owner, so state is not shared between them.\n",
|
|
688
|
+
"parameters": {
|
|
689
|
+
"type": "object",
|
|
690
|
+
"properties": {
|
|
691
|
+
"action": {
|
|
692
|
+
"default": "execute",
|
|
693
|
+
"description": "\"execute\" runs `code` in the persistent per-session REPL and is the default. \"clear\" disposes this session's kernel; the next execute starts a fresh kernel.",
|
|
694
|
+
"type": "string",
|
|
695
|
+
"enum": [
|
|
696
|
+
"execute",
|
|
697
|
+
"clear"
|
|
698
|
+
]
|
|
699
|
+
},
|
|
700
|
+
"code": {
|
|
701
|
+
"description": "Python source to execute when action is \"execute\" (required then, ignored for \"clear\").",
|
|
702
|
+
"type": "string"
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
"additionalProperties": false
|
|
706
|
+
},
|
|
707
|
+
"strict": true,
|
|
708
|
+
"deferrable": true,
|
|
709
|
+
"loadMode": "discoverable",
|
|
710
|
+
"summary": "Execute Python in a persistent per-session REPL kernel (every call is appended to the session transcript)",
|
|
711
|
+
"concurrency": "exclusive"
|
|
712
|
+
},
|
|
684
713
|
"calc": {
|
|
685
714
|
"name": "calc",
|
|
686
715
|
"label": "Calc",
|
|
@@ -2058,6 +2087,15 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2058
2087
|
"type": "string",
|
|
2059
2088
|
"description": "per-task instructions; self-contained"
|
|
2060
2089
|
},
|
|
2090
|
+
"tier": {
|
|
2091
|
+
"description": "Advisory unless autorouting is enabled; omitted routes as balanced.",
|
|
2092
|
+
"type": "string",
|
|
2093
|
+
"enum": [
|
|
2094
|
+
"fast",
|
|
2095
|
+
"balanced",
|
|
2096
|
+
"strong"
|
|
2097
|
+
]
|
|
2098
|
+
},
|
|
2061
2099
|
"executionMode": {
|
|
2062
2100
|
"description": "typed executor mode: default keeps ordinary executor behavior; ultragoal-red-team injects the Ultragoal QA/red-team prompt fragment. Prefer this over free-form assignment text (#2698).",
|
|
2063
2101
|
"type": "string",
|
|
@@ -2708,7 +2746,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2708
2746
|
"skill_discovery": {
|
|
2709
2747
|
"name": "skill_discovery",
|
|
2710
2748
|
"label": "SkillDiscovery",
|
|
2711
|
-
"description": "Discover project and user runtime skills without loading full skill content.\n\n<instruction>\n- Searches canonical GJC skill locations in precedence order: project `.gjc/skills` (ancestors from cwd to repo root, closest first), then user locations under the home directory: canonical `<config>/agent/skills`, configured legacy `<config>/skills`, and historical legacy `.gjc/skills`. `<config>` is the home-relative directory name from `GJC_CONFIG_DIR`, then `PI_CONFIG_DIR`, then `.gjc`; even an absolute-looking configured name is joined beneath `<home>`. Project scope shadows user scope; within a scope, earlier locations above win. Bundled GJC workflow skills (`deep-interview`, `ralplan`, `
|
|
2749
|
+
"description": "Discover project and user runtime skills without loading full skill content.\n\n<instruction>\n- Searches canonical GJC skill locations in precedence order: project `.gjc/skills` (ancestors from cwd to repo root, closest first), then user locations under the home directory: canonical `<config>/agent/skills`, configured legacy `<config>/skills`, and historical legacy `.gjc/skills`. `<config>` is the home-relative directory name from `GJC_CONFIG_DIR`, then `PI_CONFIG_DIR`, then `.gjc`; even an absolute-looking configured name is joined beneath `<home>`. Project scope shadows user scope; within a scope, earlier locations above win. Bundled GJC workflow skills (`autoresearch`, `deep-interview`, `ralplan`, `ultragoal`) are always available and cannot be replaced by filesystem skills.\n- Returns thin metadata only: name, description, source scope, path, and use conditions when present.\n- Claude Code (`.claude/skills`) and Codex (`.codex/skills`) layouts are explicit import sources into `.gjc`, never invokable candidates. They are not returned as candidates; instead, each convention skill found in a trusted scope is reported in `diagnostics` with the exact copy command that enables it (copy into `.gjc/skills`), so a skill placed in a documented convention location is discoverable in a normal session without being silently loaded.\n- Discovery is on by default in a normal session. When zero candidates are returned because discovery config is disabled (`skills.enabled` master switch, or `skills.trustProjectSkills` / `skills.trustUserSkills` scope trust), the result carries a `notice` explaining which setting blocked the search — an empty result without a `notice` means the searched scopes genuinely contain no matching skills.\n- When skills were scanned but not advertised (protected-name collision with a bundled workflow skill, include/ignore/disable policy filters, invalid frontmatter, shadowing), the result carries a bounded `diagnostics` list explaining why.\n- To load a selected skill's full `SKILL.md`, invoke it through the existing `skill` tool with the exact `name` returned here.\n</instruction>\n\nInput:\n- `query` (optional): words to match against skill name, description, source, or use conditions.\n- `source` (optional): `all`, `project`, or `user`.\n- `limit` (optional): maximum results, 1-50.",
|
|
2712
2750
|
"parameters": {
|
|
2713
2751
|
"type": "object",
|
|
2714
2752
|
"properties": {
|
|
@@ -2799,7 +2837,7 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2799
2837
|
"skill": {
|
|
2800
2838
|
"name": "skill",
|
|
2801
2839
|
"label": "Skill",
|
|
2802
|
-
"description": "Invoke another available skill in the current turn.\n\n<conditions>\n- A SKILL document instructs you to chain into another skill on completion (e.g. ralplan → ultragoal)\n- You finished one skill's workflow and the next step requires another skill's full prompt context\n</conditions>\n\n<instruction>\n- `name` is the skill name as it appears in `/skill:<name>` (e.g. `ralplan`, `ultragoal`, `
|
|
2840
|
+
"description": "Invoke another available skill in the current turn.\n\n<conditions>\n- A SKILL document instructs you to chain into another skill on completion (e.g. ralplan → ultragoal)\n- You finished one skill's workflow and the next step requires another skill's full prompt context\n</conditions>\n\n<instruction>\n- `name` is the skill name as it appears in `/skill:<name>` (e.g. `ralplan`, `ultragoal`, `autoresearch`, `deep-interview`)\n- `args` is the free-form argument string the skill would receive after `/skill:<name>` on the command line\n- The tool loads the callee's SKILL.md into the current turn and handles native workflow caller→callee state handoff when the caller is one of the built-in GJC workflows.\n- The chain is refused while a native workflow caller is still mid-flight. `autoresearch` chains from any of its phases (`intake`/`research`/`verdict`) — a research mission is always handoff-ready. `deep-interview` chains once its final spec is persisted (phase `handoff`), and `ralplan` chains from `final` or `handoff`. Only a mid-flight `ralplan` or `ultragoal` needs preparation first: `gjc state <skill> write --input '{\"current_phase\":\"handoff\"}' --json`; no other handoff command is needed. Runtime project/user skills do not use `gjc state <skill>`.\n- Call once per chain step. To chain `A → B → C`, A calls `skill(B)`; B's next agent turn calls `skill(C)`.\n</instruction>\n\n<critical>\n- Do NOT use this tool to \"remind yourself\" of a skill you're already running. The current SKILL.md is already in your context.\n- Do NOT chain into the same skill recursively. If a skill's flow needs another iteration, follow its in-document instructions.\n- `name` MUST be one concrete skill name, NOT a glob or wildcard. Passing `*`, `?`, or a pattern like `git-*` is rejected immediately — the `--skills '*'` launch filter is unrelated to this tool's `name`.\n- The chained skill's planning/execution-boundary rules still apply. Chaining does not grant execution approval.\n</critical>\n\n<examples>\n# Hand off from ralplan to ultragoal after an approved plan\n{\"name\": \"ultragoal\", \"args\": \"track execution of .gjc/plans/ralplan/<run-id>/pending-approval.md\"}\n\n# Trigger deep-interview with no arguments\n{\"name\": \"deep-interview\"}\n</examples>",
|
|
2803
2841
|
"parameters": {
|
|
2804
2842
|
"type": "object",
|
|
2805
2843
|
"properties": {
|
|
@@ -2856,6 +2894,30 @@ export const TOOL_CATALOG: Readonly<Record<string, ToolCatalogEntry>> = {
|
|
|
2856
2894
|
"loadMode": "essential",
|
|
2857
2895
|
"intent": "omit"
|
|
2858
2896
|
},
|
|
2897
|
+
"move_session": {
|
|
2898
|
+
"name": "move_session",
|
|
2899
|
+
"label": "Move Session",
|
|
2900
|
+
"description": "Rescope the session to a narrower working directory.\n\nUse this only when the session's working directory is a broad launcher root (for example a\nmulti-repo workspace like `~/Projects`) and the task has clearly converged on one subdirectory\nor repository: after this call, every later turn resolves relative paths and the bash default\ncwd from the new directory, and project-scoped plugins/capabilities reload for it.\n\n- `path` must be an existing directory; relative paths resolve against the current session cwd.\n The canonical target must be strictly inside the current session directory — moves to a\n parent, a sibling project, or an unrelated absolute path are refused.\n- A session can be moved this way at most once, and never while another move is running; a\n rejected call does not consume the move. Use it once the target repo is identified — not\n speculatively — because the session file and caches move with the session.\n- This tool is unavailable in subagent sessions and restricted profiles; ask the top-level\n session to rescope instead.",
|
|
2901
|
+
"parameters": {
|
|
2902
|
+
"type": "object",
|
|
2903
|
+
"properties": {
|
|
2904
|
+
"path": {
|
|
2905
|
+
"type": "string",
|
|
2906
|
+
"description": "target directory: absolute, or relative to the current session cwd"
|
|
2907
|
+
}
|
|
2908
|
+
},
|
|
2909
|
+
"required": [
|
|
2910
|
+
"path"
|
|
2911
|
+
],
|
|
2912
|
+
"additionalProperties": false
|
|
2913
|
+
},
|
|
2914
|
+
"strict": true,
|
|
2915
|
+
"deferrable": false,
|
|
2916
|
+
"loadMode": "essential",
|
|
2917
|
+
"nonAbortable": true,
|
|
2918
|
+
"concurrency": "exclusive",
|
|
2919
|
+
"intent": "omit"
|
|
2920
|
+
},
|
|
2859
2921
|
"yield": {
|
|
2860
2922
|
"name": "yield",
|
|
2861
2923
|
"label": "Submit Result",
|
package/src/tools/write.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Database } from "bun:sqlite";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
|
-
import * as path from "node:path";
|
|
4
3
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core";
|
|
5
4
|
import type { Component } from "@gajae-code/tui";
|
|
6
5
|
import { Text } from "@gajae-code/tui";
|
|
@@ -17,6 +16,7 @@ import type { ToolSession } from "../sdk";
|
|
|
17
16
|
import { Ellipsis, Hasher, type RenderCache, renderStatusLine, truncateToWidth } from "../tui";
|
|
18
17
|
import { resolveFileDisplayMode } from "../utils/file-display-mode";
|
|
19
18
|
import { parseArchivePathCandidates } from "./archive-reader";
|
|
19
|
+
import { formatFileWriteError, writeFileAtomically } from "./atomic-file-write";
|
|
20
20
|
import { assertEditableFile } from "./auto-generated-guard";
|
|
21
21
|
import {
|
|
22
22
|
type ConflictEntry,
|
|
@@ -249,11 +249,6 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
249
249
|
): Promise<AgentToolResult<WriteToolDetails>> {
|
|
250
250
|
const isZip = resolvedArchivePath.absolutePath.toLowerCase().endsWith(".zip");
|
|
251
251
|
|
|
252
|
-
const parentDir = path.dirname(resolvedArchivePath.absolutePath);
|
|
253
|
-
if (parentDir && parentDir !== ".") {
|
|
254
|
-
await fs.mkdir(parentDir, { recursive: true });
|
|
255
|
-
}
|
|
256
|
-
|
|
257
252
|
if (isZip) {
|
|
258
253
|
const zipEntries: Record<string, Uint8Array> = {};
|
|
259
254
|
|
|
@@ -275,9 +270,9 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
275
270
|
try {
|
|
276
271
|
const { zipSync } = await loadFflate();
|
|
277
272
|
const zipBuffer = zipSync(zipEntries);
|
|
278
|
-
await
|
|
273
|
+
await writeFileAtomically(resolvedArchivePath.absolutePath, zipBuffer);
|
|
279
274
|
} catch (error) {
|
|
280
|
-
throw new ToolError(error
|
|
275
|
+
throw new ToolError(formatFileWriteError(error, resolvedArchivePath.absolutePath, { destUnchanged: true }));
|
|
281
276
|
}
|
|
282
277
|
} else {
|
|
283
278
|
const archiveEntries: Record<string, string | File> = {};
|
|
@@ -304,9 +299,11 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
304
299
|
archiveEntries[resolvedArchivePath.archiveSubPath] = content;
|
|
305
300
|
|
|
306
301
|
try {
|
|
307
|
-
|
|
302
|
+
const archive = new Bun.Archive(archiveEntries);
|
|
303
|
+
const archiveBytes = await archive.bytes();
|
|
304
|
+
await writeFileAtomically(resolvedArchivePath.absolutePath, archiveBytes);
|
|
308
305
|
} catch (error) {
|
|
309
|
-
throw new ToolError(error
|
|
306
|
+
throw new ToolError(formatFileWriteError(error, resolvedArchivePath.absolutePath, { destUnchanged: true }));
|
|
310
307
|
}
|
|
311
308
|
}
|
|
312
309
|
|
|
@@ -748,9 +745,10 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
748
745
|
try {
|
|
749
746
|
await bridgePromise;
|
|
750
747
|
} catch (error) {
|
|
751
|
-
throw new ToolError(error
|
|
748
|
+
throw new ToolError(formatFileWriteError(error, absolutePath));
|
|
752
749
|
}
|
|
753
750
|
invalidateFsScanAfterWrite(absolutePath);
|
|
751
|
+
this.session.fileReadCache?.invalidate(absolutePath);
|
|
754
752
|
const displayPath = formatPathRelativeToCwd(absolutePath, this.session.cwd);
|
|
755
753
|
let resultText = `Successfully wrote ${cleanContent.length} bytes to ${displayPath}`;
|
|
756
754
|
if (stripped) {
|
|
@@ -759,8 +757,14 @@ export class WriteTool implements AgentTool<typeof writeSchema, WriteToolDetails
|
|
|
759
757
|
return { content: [{ type: "text", text: resultText }], details: {} };
|
|
760
758
|
}
|
|
761
759
|
|
|
762
|
-
|
|
760
|
+
let diagnostics: FileDiagnosticsResult | undefined;
|
|
761
|
+
try {
|
|
762
|
+
diagnostics = await this.#writethrough(absolutePath, cleanContent, signal, undefined, batchRequest);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
throw new ToolError(formatFileWriteError(error, absolutePath));
|
|
765
|
+
}
|
|
763
766
|
invalidateFsScanAfterWrite(absolutePath);
|
|
767
|
+
this.session.fileReadCache?.invalidate(absolutePath);
|
|
764
768
|
|
|
765
769
|
const displayPath = formatPathRelativeToCwd(absolutePath, this.session.cwd);
|
|
766
770
|
let resultText = `Successfully wrote ${cleanContent.length} bytes to ${displayPath}`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Escape a string for interpolation inside a double- or single-quoted XML attribute. */
|
|
2
|
+
export function escapeXmlAttribute(input: string): string {
|
|
3
|
+
if (!/[&<>"']/.test(input)) return input;
|
|
4
|
+
let output = "";
|
|
5
|
+
for (const char of input) {
|
|
6
|
+
if (char === "&") output += "&";
|
|
7
|
+
else if (char === "<") output += "<";
|
|
8
|
+
else if (char === ">") output += ">";
|
|
9
|
+
else if (char === '"') output += """;
|
|
10
|
+
else if (char === "'") output += "'";
|
|
11
|
+
else output += char;
|
|
12
|
+
}
|
|
13
|
+
return output;
|
|
14
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import * as os from "node:os";
|
|
10
10
|
import { type AuthStorage, getBundledModels } from "@gajae-code/ai/core";
|
|
11
11
|
import { decodeJwt } from "@gajae-code/ai/utils/oauth/openai-codex";
|
|
12
|
-
import { $env, readSseJson } from "@gajae-code/utils";
|
|
12
|
+
import { $env, readSseJson, sanitizeHeaderComponent } from "@gajae-code/utils";
|
|
13
13
|
import packageJson from "../../../../package.json" with { type: "json" };
|
|
14
14
|
import type { SearchResponse, SearchSource } from "../../../web/search/types";
|
|
15
15
|
import { SearchProviderError } from "../../../web/search/types";
|
|
@@ -158,7 +158,7 @@ function buildCodexHeaders(accessToken: string, accountId: string): Record<strin
|
|
|
158
158
|
"chatgpt-account-id": accountId,
|
|
159
159
|
"OpenAI-Beta": "responses=experimental",
|
|
160
160
|
originator: "pi",
|
|
161
|
-
"User-Agent": `pi/${packageJson.version} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
|
161
|
+
"User-Agent": `pi/${packageJson.version} (${sanitizeHeaderComponent(os.platform())} ${sanitizeHeaderComponent(os.release())}; ${sanitizeHeaderComponent(os.arch())})`,
|
|
162
162
|
Accept: "text/event-stream",
|
|
163
163
|
"Content-Type": "application/json",
|
|
164
164
|
};
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from "./workflow-intent-report";
|
|
6
6
|
|
|
7
7
|
export const WORKFLOW_INTENT_DIFF_CUSTOM_TYPE = "workflow-intent-diff";
|
|
8
|
-
export const WORKFLOW_INTENT_ROUTES = ["direct", "deep-interview", "ralplan", "ultragoal", "
|
|
9
|
-
export const WORKFLOW_ESCALATION_ROUTES = ["deep-interview", "ralplan", "ultragoal", "
|
|
8
|
+
export const WORKFLOW_INTENT_ROUTES = ["direct", "deep-interview", "ralplan", "ultragoal", "autoresearch"] as const;
|
|
9
|
+
export const WORKFLOW_ESCALATION_ROUTES = ["deep-interview", "ralplan", "ultragoal", "autoresearch"] as const;
|
|
10
10
|
|
|
11
11
|
export type WorkflowIntentRoute = (typeof WORKFLOW_INTENT_ROUTES)[number];
|
|
12
12
|
export type WorkflowEscalationRoute = (typeof WORKFLOW_ESCALATION_ROUTES)[number];
|
|
@@ -77,11 +77,12 @@ const ARCHITECTURE_SEQUENCE_PATTERNS = [
|
|
|
77
77
|
/\bdestructive\b/i,
|
|
78
78
|
] as const;
|
|
79
79
|
|
|
80
|
-
const
|
|
81
|
-
/\buse (?:a )?
|
|
82
|
-
/\
|
|
83
|
-
/\
|
|
84
|
-
/\
|
|
80
|
+
const AUTORESEARCH_PATTERNS = [
|
|
81
|
+
/\buse (?:a )?autoresearch\b/i,
|
|
82
|
+
/\b(?:research|investigate|experiment|benchmark|measure)\b[^.!?\n]{0,60}\b(?:mission|finding|evidence|verdict|dataset|against|compare|hypothesis)\b/i,
|
|
83
|
+
/\b(?:mission|finding|evidence|verdict|dataset|against|compare|hypothesis)\b[^.!?\n]{0,60}\b(?:research|investigate|experiment|benchmark|measure)\b/i,
|
|
84
|
+
/\brun (?:a |the )?(?:bounded )?research (?:mission|task|investigation)\b/i,
|
|
85
|
+
/\b(?:benchmark|experiment)\b[^.!?\n]{0,40}\b(?:and|then|to)\b[^.!?\n]{0,40}\b(?:report|measure|compare)\b/i,
|
|
85
86
|
] as const;
|
|
86
87
|
|
|
87
88
|
const ROOT_CAUSE_TRIGGERS = [
|
|
@@ -172,12 +173,12 @@ function classifyRoute(text: string): RouteMatch {
|
|
|
172
173
|
};
|
|
173
174
|
}
|
|
174
175
|
|
|
175
|
-
if (matchesAny(text,
|
|
176
|
+
if (matchesAny(text, AUTORESEARCH_PATTERNS)) {
|
|
176
177
|
return {
|
|
177
|
-
route: "
|
|
178
|
-
reason: "
|
|
179
|
-
recommendedInvocation: "/skill:
|
|
180
|
-
triggers: ["
|
|
178
|
+
route: "autoresearch",
|
|
179
|
+
reason: "goal-directed research mission requested",
|
|
180
|
+
recommendedInvocation: "/skill:autoresearch",
|
|
181
|
+
triggers: ["research mission"],
|
|
181
182
|
};
|
|
182
183
|
}
|
|
183
184
|
|
|
@@ -15,7 +15,7 @@ export interface WorkflowRouteCounts {
|
|
|
15
15
|
readonly "deep-interview": number;
|
|
16
16
|
readonly ralplan: number;
|
|
17
17
|
readonly ultragoal: number;
|
|
18
|
-
readonly
|
|
18
|
+
readonly autoresearch: number;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export interface WorkflowIntentReportEntry {
|
|
@@ -66,7 +66,7 @@ function emptyRouteCounts(): WorkflowRouteCounts {
|
|
|
66
66
|
"deep-interview": 0,
|
|
67
67
|
ralplan: 0,
|
|
68
68
|
ultragoal: 0,
|
|
69
|
-
|
|
69
|
+
autoresearch: 0,
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -87,8 +87,8 @@ function incrementRoute(counts: WorkflowRouteCounts, route: WorkflowIntentRoute)
|
|
|
87
87
|
return { ...counts, ralplan: counts.ralplan + 1 };
|
|
88
88
|
case "ultragoal":
|
|
89
89
|
return { ...counts, ultragoal: counts.ultragoal + 1 };
|
|
90
|
-
case "
|
|
91
|
-
return { ...counts,
|
|
90
|
+
case "autoresearch":
|
|
91
|
+
return { ...counts, autoresearch: counts.autoresearch + 1 };
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -102,8 +102,8 @@ function routeCount(counts: WorkflowRouteCounts, route: WorkflowIntentRoute): nu
|
|
|
102
102
|
return counts.ralplan;
|
|
103
103
|
case "ultragoal":
|
|
104
104
|
return counts.ultragoal;
|
|
105
|
-
case "
|
|
106
|
-
return counts.
|
|
105
|
+
case "autoresearch":
|
|
106
|
+
return counts.autoresearch;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { ASIData, MetricDirection, NumericMetricMap } from "./types";
|
|
2
|
-
export declare const METRIC_LINE_PREFIX = "METRIC";
|
|
3
|
-
export declare const ASI_LINE_PREFIX = "ASI";
|
|
4
|
-
export declare const EXPERIMENT_MAX_LINES = 10;
|
|
5
|
-
export declare const EXPERIMENT_MAX_BYTES: number;
|
|
6
|
-
export declare function parseMetricLines(output: string): Map<string, number>;
|
|
7
|
-
export declare function parseAsiLines(output: string): ASIData | null;
|
|
8
|
-
export declare function mergeAsi(base: ASIData | null, override: ASIData | undefined): ASIData | undefined;
|
|
9
|
-
export declare function commas(value: number): string;
|
|
10
|
-
export declare function fmtNum(value: number, decimals?: number): string;
|
|
11
|
-
export declare function formatNum(value: number | null, unit: string): string;
|
|
12
|
-
export declare function formatElapsed(milliseconds: number): string;
|
|
13
|
-
export declare function killTree(pid: number, signal?: NodeJS.Signals | number): void;
|
|
14
|
-
export declare function isBetter(current: number, best: number, direction: MetricDirection): boolean;
|
|
15
|
-
export declare function inferMetricUnitFromName(name: string): string;
|
|
16
|
-
export declare function normalizePathSpec(value: string): string;
|
|
17
|
-
export declare function pathMatchesSpec(pathValue: string, specValue: string): boolean;
|
|
18
|
-
export declare function dedupeStrings(values: readonly string[]): string[];
|
|
19
|
-
export declare function ensureNumericMetricMap(value: NumericMetricMap | undefined): NumericMetricMap;
|
|
20
|
-
export declare function sanitizeAsi(value: {
|
|
21
|
-
[key: string]: unknown;
|
|
22
|
-
} | undefined): ASIData | undefined;
|
|
23
|
-
export declare function tryGitStatus(cwd: string): Promise<string>;
|
|
24
|
-
export declare function tryGitPrefix(cwd: string): Promise<string>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { SessionEntry } from "../session/session-manager";
|
|
2
|
-
import type { RunRow, SessionRow } from "./storage";
|
|
3
|
-
import type { AutoresearchRuntime, ExperimentResult, ExperimentState, MetricDef, MetricDirection, NumericMetricMap, ReconstructedControlState, RuntimeStore } from "./types";
|
|
4
|
-
export declare function createExperimentState(): ExperimentState;
|
|
5
|
-
export declare function createSessionRuntime(): AutoresearchRuntime;
|
|
6
|
-
export declare function cloneExperimentState(state: ExperimentState): ExperimentState;
|
|
7
|
-
export declare function currentResults(results: ExperimentResult[], segment: number): ExperimentResult[];
|
|
8
|
-
export declare function findBaselineResult(results: ExperimentResult[], segment: number): ExperimentResult | null;
|
|
9
|
-
export declare function findBaselineMetric(results: ExperimentResult[], segment: number): number | null;
|
|
10
|
-
export declare function findBestKeptMetric(results: ExperimentResult[], segment: number, direction: MetricDirection): number | null;
|
|
11
|
-
export declare function findBaselineRunNumber(results: ExperimentResult[], segment: number): number | null;
|
|
12
|
-
export declare function findBaselineSecondary(results: ExperimentResult[], segment: number, knownMetrics: MetricDef[]): NumericMetricMap;
|
|
13
|
-
export declare function sortedMedian(values: number[]): number;
|
|
14
|
-
export declare function computeConfidence(results: ExperimentResult[], segment: number, direction: MetricDirection): number | null;
|
|
15
|
-
export declare function buildExperimentState(session: SessionRow, loggedRuns: RunRow[]): ExperimentState;
|
|
16
|
-
export declare function reconstructControlState(entries: SessionEntry[]): ReconstructedControlState;
|
|
17
|
-
export declare function createRuntimeStore(): RuntimeStore;
|