@gajae-code/coding-agent 0.17.6 → 0.17.7
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 +34 -0
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/commands/sdk.d.ts +7 -1
- package/dist/types/config/model-profile-ownership.d.ts +74 -0
- package/dist/types/config/model-registry.d.ts +2 -1
- package/dist/types/config/settings-schema.d.ts +32 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +4 -1
- package/dist/types/sdk/lifecycle/service.d.ts +2 -0
- package/dist/types/sdk/lifecycle-session.d.ts +5 -1
- package/dist/types/sdk/session-directory.d.ts +1 -0
- package/dist/types/sdk/session-list.d.ts +11 -0
- package/dist/types/sdk/startup-capability.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +6 -0
- package/dist/types/session/internal/managed-session-scope.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +6 -0
- package/dist/types/setup/model-onboarding-guidance.d.ts +18 -0
- package/dist/types/task/delegation-hint.d.ts +53 -0
- package/examples/README.md +3 -3
- package/examples/custom-tools/README.md +1 -1
- package/examples/hooks/README.md +1 -1
- package/package.json +7 -7
- package/scripts/generate-sdk-operation-inventory.ts +6 -0
- package/src/cli/config-cli.ts +2 -0
- package/src/cli/public-command-errors.ts +6 -0
- package/src/commands/sdk.ts +361 -117
- package/src/config/model-profile-ownership.ts +303 -0
- package/src/config/model-registry.ts +53 -14
- package/src/config/settings-schema.ts +81 -0
- package/src/internal-urls/docs-index.generated.ts +18 -17
- package/src/modes/controllers/extension-ui-controller.ts +6 -0
- package/src/modes/controllers/selector-controller.ts +3 -29
- package/src/sdk/broker/broker.ts +120 -23
- package/src/sdk/broker/lifecycle.ts +89 -13
- package/src/sdk/cli/session-cli.ts +45 -9
- package/src/sdk/host/control/dispatch.ts +6 -0
- package/src/sdk/lifecycle/service.ts +186 -3
- package/src/sdk/lifecycle-session.ts +35 -8
- package/src/sdk/protocol/operation-inventory.generated.json +33 -0
- package/src/sdk/protocol/operation-registry.ts +5 -1
- package/src/sdk/session-directory.ts +1 -1
- package/src/sdk/session-list.ts +47 -0
- package/src/sdk/session.ts +290 -114
- package/src/sdk/startup-capability.ts +2 -1
- package/src/session/agent-session.ts +102 -4
- package/src/session/internal/managed-session-scope.ts +81 -17
- package/src/session/session-manager.ts +70 -11
- package/src/setup/model-onboarding-guidance.ts +26 -0
- package/src/task/delegation-hint.ts +578 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.17.7] - 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Add versioned durable ownership storage and transcript markers for transactional model-profile changes.
|
|
10
|
+
|
|
11
|
+
- Add an opt-in, off-by-default transient Kev delegation notice from bounded local aggregates, including remaining context budget ratio and the pending/in-progress task count in the largest plan phase. A successful todo update with at least three active steps in one phase can trigger a hint. It does not alter prompts, task arguments, or saved sessions; enforcement and decision telemetry are not included.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Require explicit replacement before deleting a profile owned by a durable default or active session.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Initialize owned SDK model catalogs with final scoped settings before the first catalog pass.
|
|
20
|
+
|
|
21
|
+
- Initialize owned SDK model registries once with scoped settings, and keep source-host construction within owner-bound readiness cancellation and rollback.
|
|
22
|
+
|
|
23
|
+
- SDK `session.list` retries one complete identity-bound scan after a concurrent transcript change and returns a path-free, target-correlated reason if selection still fails; exact saved-session lookups cannot be mixed with page cursors, and resolution remains fail-closed (#5887).
|
|
24
|
+
|
|
25
|
+
- Preserve pre-session rollback proof when theme startup is interrupted and revoke published readiness markers through bounded off-thread cleanup.
|
|
26
|
+
|
|
27
|
+
- Interactive sessions now expose their own async-job snapshot to extensions and the SDK, so `runtime.jobs.list` reports the session's running jobs, recent jobs, and pending delivery instead of failing with `resource_gone`.
|
|
28
|
+
- `gjc sdk session` failures caused by a typed `resource_gone` now carry a fixed diagnostic that distinguishes absent resource state from an empty result, without changing the public error code, retryability, or exit code.
|
|
29
|
+
|
|
30
|
+
- SDK lifecycle failures caused by a broker idempotency conflict now carry a single fixed public diagnostic (`lifecycle_idempotency_conflict`) in both JSON and text command-error output, so an operator can tell a conflict from an ordinary `operation_failed` without the broker's raw message, paths, or credentials reaching the envelope. The diagnostic text names no cause and does not suggest that another request key is safe. The public failure code, effect proof, retryability, and exit code are unchanged.
|
|
31
|
+
- `gjc sdk session raw global --op session.lookup` no longer prints the broker's own idempotency-conflict message. That route returns its structured outcome directly, so it bypasses the public error envelope and its 8192-byte budget, and a hostile or oversized broker message could expose request keys, paths, or credentials in CLI output. The exact `idempotency_conflict` code now carries the same fixed, cause-neutral text as the public diagnostic; lookup status, error code, certainty, reconciliation guidance, and exit code are unchanged, and every other lookup code is left untouched.
|
|
32
|
+
|
|
33
|
+
- `session.lookup` for a `session.create` now recovers the recorded outcome when the lookup target matches the create target. The broker fingerprinted the raw lookup target while the create path fingerprinted its normalized input (resolved `cwd` plus the derived `stateRoot`), so every lookup reported `idempotency_conflict` and callers could not reconcile a lost create acknowledgement. Lookup targets now pass through the same normalization before fingerprinting; a genuinely different target still conflicts, and an invalid lookup target is rejected as `invalid_input`. Create rows recorded before target-bound identities, which carry a raw-target fingerprint, stay recoverable: lookup falls back to the raw fingerprint only for that exact legacy identity (#5933).
|
|
34
|
+
|
|
35
|
+
- Answer an SDK `turn.prompt`/`turn.abort_and_prompt` submitted to a session with no selected model with the typed `model_not_selected` control error and a fixed public message, instead of a generic `internal` failure. The local onboarding guidance (providers, commands, environment variables, setup paths) stays local-only and is not published on the control protocol, missing credentials and arbitrary exceptions keep their existing generic classification, and the rejection still happens before admission so no turn is accepted.
|
|
36
|
+
|
|
37
|
+
- Remove per-process test agent and log isolation directories after each Bun test file completes, while keeping the isolated log sink available throughout the run. Set `GJC_TEST_KEEP_TMP=1` to preserve per-file test sandboxes and their isolated state for debugging, including failed preload initialization (#5852).
|
|
38
|
+
|
|
5
39
|
## [0.17.6] - 2026-09-24
|
|
6
40
|
|
|
7
41
|
### Fixed
|
|
@@ -75,8 +75,10 @@ export type PublicEvidenceStatus = {
|
|
|
75
75
|
};
|
|
76
76
|
export declare const PUBLIC_COMMAND_DIAGNOSTICS: {
|
|
77
77
|
readonly macos_nofile_limit_low: "The macOS open-file limit is below the recommended minimum; increase it before starting additional concurrent work.";
|
|
78
|
+
readonly sdk_resource_gone: "The requested resource is not available from this session endpoint; this reports absent resource state, not an empty result.";
|
|
78
79
|
readonly router_cleanup_failed: "SDK session Router cleanup failed.";
|
|
79
80
|
readonly broker_cleanup_failed: "SDK broker client cleanup failed.";
|
|
81
|
+
readonly lifecycle_idempotency_conflict: "The broker reported an idempotency conflict. Reconcile existing lifecycle state before deciding whether another request is safe.";
|
|
80
82
|
readonly usage_transport_exclusive: "Specify exactly one of --stdio or --socket <path>.";
|
|
81
83
|
readonly usage_duplicate_option: "Each option on this command may occur at most once.";
|
|
82
84
|
readonly usage_unknown_argument: "An unrecognized argument was supplied; re-read the command help for its accepted grammar.";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Command } from "@gajae-code/utils/cli";
|
|
2
2
|
import type { Args as ParsedArgs } from "../cli/args";
|
|
3
3
|
import { applyStartupModelProfiles } from "../main";
|
|
4
|
-
import {
|
|
4
|
+
import { initTheme } from "../modes/theme/theme";
|
|
5
|
+
import { type SessionLifecycleLaunchRequest, writeSessionLifecycleReady } from "../sdk/broker/lifecycle";
|
|
6
|
+
import { createLifecycleAgentSession } from "../sdk/lifecycle-session";
|
|
5
7
|
import { SessionManager } from "../session/session-manager";
|
|
6
8
|
export declare function lifecycleArgs(request: SessionLifecycleLaunchRequest, cwd: string, agentDir: string): Promise<ParsedArgs>;
|
|
7
9
|
/**
|
|
@@ -119,6 +121,10 @@ export declare function runSessionHost(timing?: {
|
|
|
119
121
|
cwd?: string;
|
|
120
122
|
processIncarnation?: (pid: number) => string | undefined;
|
|
121
123
|
applyStartupModelProfiles?: typeof applyStartupModelProfiles;
|
|
124
|
+
initTheme?: typeof initTheme;
|
|
125
|
+
createLifecycleAgentSession?: typeof createLifecycleAgentSession;
|
|
126
|
+
writeSessionLifecycleReady?: typeof writeSessionLifecycleReady;
|
|
127
|
+
writeMcpConfig?: (filePath: string, contents: string) => Promise<number>;
|
|
122
128
|
}): Promise<void>;
|
|
123
129
|
export type SdkInternalArgv = {
|
|
124
130
|
action: "broker-internal";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { SettingsAtomicPatch } from "./settings";
|
|
2
|
+
export type ModelProfileOwnershipMarker = {
|
|
3
|
+
kind: "inherit";
|
|
4
|
+
} | {
|
|
5
|
+
kind: "cleared";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "profile";
|
|
8
|
+
profile: string;
|
|
9
|
+
};
|
|
10
|
+
export interface DurableModelProfileOwnership {
|
|
11
|
+
schemaVersion: 1;
|
|
12
|
+
version: number;
|
|
13
|
+
marker: ModelProfileOwnershipMarker;
|
|
14
|
+
}
|
|
15
|
+
export interface ModelProfileOwnershipSettings {
|
|
16
|
+
getGlobal(path: "modelProfile.ownership" | "modelProfile.default"): unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface DurableModelProfileOwnershipCommit {
|
|
19
|
+
ownership: DurableModelProfileOwnership;
|
|
20
|
+
wrote: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface DurableModelProfileOwnershipStore extends ModelProfileOwnershipSettings {
|
|
23
|
+
commitAtomicBatchWithCurrent(buildPatches: (current: Readonly<Record<string, unknown>>) => Promise<readonly SettingsAtomicPatch[]> | readonly SettingsAtomicPatch[]): Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
export declare const MODEL_PROFILE_OWNERSHIP_ENTRY = "model_profile_ownership";
|
|
26
|
+
export declare function validateModelProfileOwnershipMarker(value: unknown): ModelProfileOwnershipMarker | undefined;
|
|
27
|
+
export declare function validateDurableModelProfileOwnership(value: unknown): DurableModelProfileOwnership | undefined;
|
|
28
|
+
export declare class InvalidModelProfileOwnershipError extends Error {
|
|
29
|
+
readonly code = "model_profile_ownership_invalid";
|
|
30
|
+
constructor();
|
|
31
|
+
}
|
|
32
|
+
export declare class UnresolvedModelProfileOwnershipError extends Error {
|
|
33
|
+
readonly profileName: string;
|
|
34
|
+
readonly code = "model_profile_unresolved";
|
|
35
|
+
constructor(profileName: string);
|
|
36
|
+
}
|
|
37
|
+
export declare class ModelProfileReplacementRequiredError extends Error {
|
|
38
|
+
readonly profileName: string;
|
|
39
|
+
readonly code = "model_profile_replacement_required";
|
|
40
|
+
constructor(profileName: string);
|
|
41
|
+
}
|
|
42
|
+
export declare class ModelProfileOwnershipConflictError extends Error {
|
|
43
|
+
readonly expectedVersion: number;
|
|
44
|
+
readonly actualVersion: number;
|
|
45
|
+
readonly actualMarker?: ModelProfileOwnershipMarker | undefined;
|
|
46
|
+
readonly code = "model_profile_ownership_conflict";
|
|
47
|
+
constructor(expectedVersion: number, actualVersion: number, actualMarker?: ModelProfileOwnershipMarker | undefined);
|
|
48
|
+
}
|
|
49
|
+
export declare class ModelProfileApplyCommittedError extends Error {
|
|
50
|
+
readonly profileName: string;
|
|
51
|
+
readonly committedVersion: number;
|
|
52
|
+
readonly code = "model_profile_apply_committed";
|
|
53
|
+
constructor(profileName: string, committedVersion: number, cause: unknown);
|
|
54
|
+
}
|
|
55
|
+
export interface ProfileOwnershipChangedEvent {
|
|
56
|
+
type: "profile_ownership_changed";
|
|
57
|
+
transitionId: string;
|
|
58
|
+
source: "session" | "durable" | "recovery";
|
|
59
|
+
oldMarker: ModelProfileOwnershipMarker;
|
|
60
|
+
newMarker: ModelProfileOwnershipMarker;
|
|
61
|
+
oldSessionId: string;
|
|
62
|
+
sessionId: string;
|
|
63
|
+
observedDurableVersion: number;
|
|
64
|
+
committedDurableVersion?: number;
|
|
65
|
+
outcome: "committed" | "failed" | "reconciled";
|
|
66
|
+
}
|
|
67
|
+
export declare function readDurableModelProfileOwnership(settings: ModelProfileOwnershipSettings): DurableModelProfileOwnership;
|
|
68
|
+
export declare function readDurableModelProfileOwnershipFromRaw(raw: Readonly<Record<string, unknown>>): DurableModelProfileOwnership;
|
|
69
|
+
export declare function resolveEffectiveModelProfileMarker(sessionMarker: ModelProfileOwnershipMarker | undefined, durable: DurableModelProfileOwnership): ModelProfileOwnershipMarker;
|
|
70
|
+
export declare function resolveOwnedModelProfileName(marker: ModelProfileOwnershipMarker, profiles: ReadonlyMap<string, unknown>): string | undefined;
|
|
71
|
+
export declare function nextDurableModelProfileOwnership(current: DurableModelProfileOwnership, marker: ModelProfileOwnershipMarker): DurableModelProfileOwnership;
|
|
72
|
+
export declare function commitDurableModelProfileOwnershipWithResult(settings: DurableModelProfileOwnershipStore, marker: ModelProfileOwnershipMarker, extraPatches?: readonly SettingsAtomicPatch[], validateCurrent?: () => Promise<void> | void, observedOwnership?: DurableModelProfileOwnership): Promise<DurableModelProfileOwnershipCommit>;
|
|
73
|
+
export declare function commitDurableModelProfileOwnership(settings: DurableModelProfileOwnershipStore, marker: ModelProfileOwnershipMarker, extraPatches?: readonly SettingsAtomicPatch[], validateCurrent?: () => Promise<void> | void, observedOwnership?: DurableModelProfileOwnership): Promise<DurableModelProfileOwnership>;
|
|
74
|
+
export declare function modelProfileOwnershipMarkersEqual(left: ModelProfileOwnershipMarker | undefined, right: ModelProfileOwnershipMarker | undefined): boolean;
|
|
@@ -367,7 +367,7 @@ export declare class ModelRegistry {
|
|
|
367
367
|
/**
|
|
368
368
|
* @param authStorage - Auth storage for API key resolution
|
|
369
369
|
*/
|
|
370
|
-
constructor(authStorage: AuthStorage, modelsPath?: string, registrySettings?: Pick<Settings, "get" | "getGlobal"
|
|
370
|
+
constructor(authStorage: AuthStorage, modelsPath?: string, registrySettings?: Pick<Settings, "get" | "getGlobal"> & Partial<Pick<Settings, "commitAtomicBatchWithCurrent">>, modelPresetRegistryDependencies?: ModelPresetRegistryDependencies);
|
|
371
371
|
dispose(): Promise<void>;
|
|
372
372
|
onCatalogChanged(listener: () => void): () => void;
|
|
373
373
|
/** Replace the read-only settings snapshot used by profile-scoped resolution. */
|
|
@@ -394,6 +394,7 @@ export declare class ModelRegistry {
|
|
|
394
394
|
*/
|
|
395
395
|
getError(): ConfigError | undefined;
|
|
396
396
|
getModelProfiles(): Map<string, ModelProfileDefinition>;
|
|
397
|
+
assertCurrentModelProfileExists(name: string): void;
|
|
397
398
|
getModelProfile(name: string): ModelProfileDefinition | undefined;
|
|
398
399
|
getAvailableModelProfileNames(): string[];
|
|
399
400
|
saveCustomModelProfile(name: string, definition: ModelProfileConfig): Promise<ModelProfileDefinition>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Effort } from "@gajae-code/ai/model-thinking";
|
|
2
2
|
import { type EditMode } from "../utils/edit-mode";
|
|
3
3
|
import { type AutoroutingLocalIssue, type AutoroutingProvenance, type AutoroutingSetup, type AutoroutingTierMapInput } from "./autorouting-contract";
|
|
4
|
+
import { type DurableModelProfileOwnership } from "./model-profile-ownership";
|
|
4
5
|
import type { ModelSelectorValue } from "./model-selector-value";
|
|
5
6
|
import { type SkillDiscoverySettings } from "./skill-settings-defaults";
|
|
6
7
|
/** Unified settings schema - single source of truth for all settings.
|
|
@@ -529,6 +530,18 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
529
530
|
readonly options: "runtime";
|
|
530
531
|
};
|
|
531
532
|
};
|
|
533
|
+
readonly "modelProfile.ownership": {
|
|
534
|
+
readonly type: "optional-object";
|
|
535
|
+
readonly default: undefined;
|
|
536
|
+
readonly jsonSchema: JsonSchemaObject;
|
|
537
|
+
readonly validate: (value: unknown) => {
|
|
538
|
+
path: string;
|
|
539
|
+
code: string;
|
|
540
|
+
reason: string;
|
|
541
|
+
detail: string;
|
|
542
|
+
}[];
|
|
543
|
+
readonly _value: DurableModelProfileOwnership;
|
|
544
|
+
};
|
|
532
545
|
readonly "modelProfile.proxyProvider": {
|
|
533
546
|
readonly type: "string";
|
|
534
547
|
readonly default: undefined;
|
|
@@ -3994,6 +4007,25 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
3994
4007
|
readonly description: "Encourage the agent to delegate work to subagents unless changes are trivial (on by default when executor/planner run on a different provider than the default role)";
|
|
3995
4008
|
};
|
|
3996
4009
|
};
|
|
4010
|
+
readonly "task.delegationHint.mode": {
|
|
4011
|
+
readonly type: "enum";
|
|
4012
|
+
readonly values: readonly ["off", "hint"];
|
|
4013
|
+
readonly default: "off";
|
|
4014
|
+
readonly ui: {
|
|
4015
|
+
readonly tab: "tasks";
|
|
4016
|
+
readonly label: "Delegation Decision Hint";
|
|
4017
|
+
readonly description: "Opt in to transient local-only Kev advice after observable edit activity. Notices never alter prompts, task arguments, or saved sessions.";
|
|
4018
|
+
readonly options: readonly [{
|
|
4019
|
+
readonly value: "off";
|
|
4020
|
+
readonly label: "Off";
|
|
4021
|
+
readonly description: "Do not request decision hints (default)";
|
|
4022
|
+
}, {
|
|
4023
|
+
readonly value: "hint";
|
|
4024
|
+
readonly label: "Hint";
|
|
4025
|
+
readonly description: "Show ephemeral user-facing advice from the local Kev service";
|
|
4026
|
+
}];
|
|
4027
|
+
};
|
|
4028
|
+
};
|
|
3997
4029
|
readonly "task.simple": {
|
|
3998
4030
|
readonly type: "enum";
|
|
3999
4031
|
readonly values: readonly ["default", "schema-free", "independent"];
|
|
@@ -178,8 +178,11 @@ export declare function observeProcessForTest(pid: number, expectedIncarnation:
|
|
|
178
178
|
*/
|
|
179
179
|
export declare function reapDeadLifecycleMarkers(root: string, limit?: number): Promise<number>;
|
|
180
180
|
export declare function writeEffectMarker(root: string, id: string, marker: EffectMarker): Promise<void>;
|
|
181
|
+
export declare class LifecycleReadinessCleanupError extends Error {
|
|
182
|
+
constructor(cause: unknown);
|
|
183
|
+
}
|
|
181
184
|
/** The child writes this only after its endpoint and semantic ready event are both live. */
|
|
182
|
-
export declare function writeSessionLifecycleReady(root: string, id: string, effectMarker: string): Promise<void>;
|
|
185
|
+
export declare function writeSessionLifecycleReady(root: string, id: string, effectMarker: string, canPublish?: () => boolean, onPublishing?: (revoke: () => Promise<boolean>) => void, onPublished?: () => void): Promise<void>;
|
|
183
186
|
export interface LifecycleTranscriptEvidence {
|
|
184
187
|
digest: string;
|
|
185
188
|
identity: SessionLifecycleTranscriptIdentity;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ScopeRequestV1, type SdkSearchResultV1 } from "../broker/session-scope";
|
|
2
2
|
import type { SessionBindingAuthority } from "../session-authority";
|
|
3
|
+
import { type SessionListSavedSessionOmission } from "../session-list";
|
|
3
4
|
export type { SessionBindingAuthority, SessionEndpointAuthority } from "../session-authority";
|
|
4
5
|
export type SessionLifecycleOperation = "session.create" | "session.fork" | "session.resume" | "session.close" | "session.delete" | "session.reconcile_uncertain" | "session.lookup" | "session.list";
|
|
5
6
|
export type SessionLifecycleMutationOperation = Exclude<SessionLifecycleOperation, "session.lookup" | "session.list">;
|
|
@@ -171,6 +172,7 @@ export interface SessionLifecycleListResult {
|
|
|
171
172
|
readonly sessions: readonly SessionLifecycleListEntry[];
|
|
172
173
|
readonly warnings: readonly string[];
|
|
173
174
|
readonly savedSession?: SessionLifecycleSavedSession;
|
|
175
|
+
readonly savedSessionOmission?: SessionListSavedSessionOmission;
|
|
174
176
|
}
|
|
175
177
|
export type SessionScopedListResult = SdkSearchResultV1;
|
|
176
178
|
export interface SessionCreateResult {
|
|
@@ -51,5 +51,9 @@ export type CreateLifecycleAgentSessionOptions = Omit<CreateAgentSessionOptions,
|
|
|
51
51
|
/** Broker-issued lifecycle request identity published with host registration. */
|
|
52
52
|
lifecycleRequestId?: string;
|
|
53
53
|
};
|
|
54
|
+
export interface SdkLifecycleStartupOwner {
|
|
55
|
+
readonly capability: SdkStartupCapability;
|
|
56
|
+
readonly rollback: SdkStartupRollbackTracker;
|
|
57
|
+
}
|
|
54
58
|
/** Internal lifecycle-only session construction with an owner-bound SDK startup result. */
|
|
55
|
-
export declare function createLifecycleAgentSession(options?: CreateLifecycleAgentSessionOptions): Promise<CreateLifecycleAgentSessionResult>;
|
|
59
|
+
export declare function createLifecycleAgentSession(options?: CreateLifecycleAgentSessionOptions, owner?: SdkLifecycleStartupOwner): Promise<CreateLifecycleAgentSessionResult>;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export type SessionListPageRecord = Record<string, unknown>;
|
|
2
|
+
export type SessionListSavedSessionOmissionReason = "scope_unavailable" | "candidate_scan_failed" | "candidate_not_found" | "candidate_ambiguous" | "candidate_invalid" | "identity_incomplete";
|
|
3
|
+
export declare const SESSION_LIST_SAVED_SESSION_OMISSION_DETAIL_CODES: readonly ["cwd_missing", "cwd_not_directory", "identity_unavailable", "network_unsupported", "sessions_root_unavailable", "binding_conflict", "binding_invalid", "migration_busy", "atomic_unavailable", "invalid_request", "durability_failed", "durability_not_provable", "capacity_exceeded", "scan_failed", "unsafe_root", "invalid_candidate", "invalid_header", "unreadable_candidate", "source_changed", "cwd_not_found", "cwd_not_utf8", "cwd_network_unsupported", "cwd_identity_unavailable", "cwd_io_error"];
|
|
4
|
+
export type SessionListSavedSessionOmissionDetailCode = (typeof SESSION_LIST_SAVED_SESSION_OMISSION_DETAIL_CODES)[number];
|
|
5
|
+
/** Path-free diagnostic for a requested managed transcript that could not be selected safely. */
|
|
6
|
+
export interface SessionListSavedSessionOmission {
|
|
7
|
+
readonly sessionId: string;
|
|
8
|
+
readonly reason: SessionListSavedSessionOmissionReason;
|
|
9
|
+
readonly detailCode?: SessionListSavedSessionOmissionDetailCode;
|
|
10
|
+
readonly candidateCount?: number;
|
|
11
|
+
readonly missingIdentityFields?: readonly ("nlink" | "ctimeNs")[];
|
|
12
|
+
}
|
|
2
13
|
export type SessionListTraversalErrorKind = "malformed_page" | "repeated_cursor" | "page_budget_exceeded";
|
|
3
14
|
export declare class SessionListTraversalError extends Error {
|
|
4
15
|
#private;
|
|
@@ -53,7 +53,7 @@ export declare class SdkStartupCapability {
|
|
|
53
53
|
readonly readiness: "immediate" | "deferred";
|
|
54
54
|
readonly lifecycleRequestId?: string | undefined;
|
|
55
55
|
get cancelled(): boolean;
|
|
56
|
-
cancel(): void;
|
|
56
|
+
cancel(failure?: SdkStartupFailure): void;
|
|
57
57
|
/**
|
|
58
58
|
* The broker-issued, session-scoped readiness intent this child was launched
|
|
59
59
|
* with. It is carried on the capability rather than read from the ambient
|
|
@@ -882,6 +882,10 @@ export declare class AgentSession {
|
|
|
882
882
|
/** Join the retained teardown owner without allocating another public deadline. */
|
|
883
883
|
awaitDisposeCompletion(): Promise<void>;
|
|
884
884
|
setDisposeTimeoutForTests(timeoutMs: number): void;
|
|
885
|
+
/** Bind coordinator runtime-state persistence to this session in tests. */
|
|
886
|
+
setCoordinatorRuntimeStateFileForTests(stateFile: string): void;
|
|
887
|
+
/** Read the test-only coordinator runtime-state path bound to this session. */
|
|
888
|
+
getCoordinatorRuntimeStateFileForTests(): string | undefined;
|
|
885
889
|
trackPostPromptTaskForTests(task: Promise<void>): void;
|
|
886
890
|
requestWorkerIntegrationForTests(): void;
|
|
887
891
|
/**
|
|
@@ -944,6 +948,8 @@ export declare class AgentSession {
|
|
|
944
948
|
awaitSessionSettlement(): Promise<void>;
|
|
945
949
|
/** Test seam: hold prompt admission while bypassing a pending selection fence. */
|
|
946
950
|
runWithPromptAdmissionForTests(body: () => Promise<void>): Promise<void>;
|
|
951
|
+
/** Enable sidecar write failure reporting for retry-test teardown. */
|
|
952
|
+
trackCoordinatorRuntimeStatePersistenceFailuresForTests(): void;
|
|
947
953
|
/** Test seam: await all currently admitted coordinator sidecar writes. */
|
|
948
954
|
awaitCoordinatorRuntimeStatePersistenceForTests(): Promise<void>;
|
|
949
955
|
queueCoordinatorRuntimeStatePersistForTests(event: AgentSessionEvent, gate: Promise<void>): Promise<void>;
|
|
@@ -62,6 +62,7 @@ export type ManagedCandidateListing = {
|
|
|
62
62
|
foreignCount: number;
|
|
63
63
|
invalid: readonly {
|
|
64
64
|
code: string;
|
|
65
|
+
sessionId?: string;
|
|
65
66
|
}[];
|
|
66
67
|
} | {
|
|
67
68
|
kind: "error";
|
|
@@ -107,6 +108,9 @@ export interface ManagedLockReleaseTestEvent {
|
|
|
107
108
|
export declare const ManagedSessionScopeTestHooks: {
|
|
108
109
|
beforeVerifiedDelete?: (event: ManagedVerifiedDeleteTestEvent) => void | Promise<void>;
|
|
109
110
|
beforeManagedLockRelease?: (event: ManagedLockReleaseTestEvent) => void | Promise<void>;
|
|
111
|
+
afterCandidatePreflight?: (event: {
|
|
112
|
+
readonly sessionId?: string;
|
|
113
|
+
}) => void;
|
|
110
114
|
};
|
|
111
115
|
declare function scopeDigest(platform: "posix" | "win32", canonicalPath: string): string;
|
|
112
116
|
export declare const computeManagedScopeDigest: typeof scopeDigest;
|
|
@@ -4,6 +4,7 @@ import { type AgentMessage } from "@gajae-code/agent-core";
|
|
|
4
4
|
import type { ConfiguredModelChainEntry as SharedConfiguredModelChainEntry } from "@gajae-code/agent-core/compaction";
|
|
5
5
|
import type { ImageContent, Message, MessageAttribution, ServiceTier, TextContent } from "@gajae-code/ai/core";
|
|
6
6
|
import type * as native from "@gajae-code/natives";
|
|
7
|
+
import { type ModelProfileOwnershipMarker } from "../config/model-profile-ownership";
|
|
7
8
|
import type { TtsrInjectionRecord } from "../export/ttsr";
|
|
8
9
|
import type { ManagedLegacyLocalMigrationSource } from "../internal-urls/local-protocol";
|
|
9
10
|
import { ArtifactManager } from "./artifacts";
|
|
@@ -603,6 +604,8 @@ export interface SessionContext {
|
|
|
603
604
|
models: Record<string, string>;
|
|
604
605
|
/** Configured fallback chains for model roles on the active branch. */
|
|
605
606
|
configuredModelChains: Record<string, ConfiguredModelChain>;
|
|
607
|
+
/** Effective-branch profile owner decision; absent means the legacy inherit marker. */
|
|
608
|
+
modelProfileOwnershipMarker?: ModelProfileOwnershipMarker;
|
|
606
609
|
/** Names of TTSR rules that have been injected this session */
|
|
607
610
|
injectedTtsrRules: string[];
|
|
608
611
|
/** Rich TTSR rule injection records for repeat resume. */
|
|
@@ -1524,6 +1527,9 @@ export declare class SessionManager {
|
|
|
1524
1527
|
appendCompaction<T = unknown>(summary: string, shortSummary: string | undefined, firstKeptEntryId: string, tokensBefore: number, details?: T, fromExtension?: boolean, preserveData?: Record<string, unknown>): string;
|
|
1525
1528
|
/** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */
|
|
1526
1529
|
appendCustomEntry(customType: string, data?: unknown): string;
|
|
1530
|
+
appendPreparedModelProfileOwnershipMarker(prepared: PreparedNewSession, marker: ModelProfileOwnershipMarker): string;
|
|
1531
|
+
appendModelProfileOwnershipMarker(marker: ModelProfileOwnershipMarker): string;
|
|
1532
|
+
getModelProfileOwnershipMarker(): ModelProfileOwnershipMarker | undefined;
|
|
1527
1533
|
/**
|
|
1528
1534
|
* Append a root marker that starts a fresh active branch without changing the
|
|
1529
1535
|
* session id or deleting earlier durable entries. Subsequent messages descend
|
|
@@ -5,5 +5,23 @@ export declare const MODEL_ONBOARDING_OAUTH_COMMAND = "/provider login [provider
|
|
|
5
5
|
export declare function formatModelOnboardingGuidance(): string;
|
|
6
6
|
export declare function formatModelOnboardingInlineHint(): string;
|
|
7
7
|
export declare function formatNoModelOnboardingError(): string;
|
|
8
|
+
/** Control-protocol code for a prompt refused because the session has no model. */
|
|
9
|
+
export declare const MODEL_NOT_SELECTED_CODE = "model_not_selected";
|
|
10
|
+
/**
|
|
11
|
+
* Fixed public text for {@link MODEL_NOT_SELECTED_CODE}. The onboarding
|
|
12
|
+
* guidance names providers, commands, environment variables and local setup
|
|
13
|
+
* paths, so it stays local-only; external clients get this constant instead.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MODEL_NOT_SELECTED_PUBLIC_MESSAGE = "No model is selected for this session. Select a model before submitting a prompt.";
|
|
16
|
+
/**
|
|
17
|
+
* Missing-model prompt preflight failure. The message keeps the full local
|
|
18
|
+
* onboarding guidance for the TUI and in-process callers; the `code` is what
|
|
19
|
+
* lets the SDK control surface answer with a safe, known diagnostic instead of
|
|
20
|
+
* a generic internal error.
|
|
21
|
+
*/
|
|
22
|
+
export declare class NoModelSelectedError extends Error {
|
|
23
|
+
readonly code = "model_not_selected";
|
|
24
|
+
constructor();
|
|
25
|
+
}
|
|
8
26
|
export declare function formatNoCredentialOnboardingError(providerId: string): string;
|
|
9
27
|
export declare function formatNoModelsAvailableFallback(): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type AutoroutingTier } from "../config/autorouting-contract";
|
|
2
|
+
export declare const KEV_SYSTEMONE_ENDPOINT = "http://127.0.0.1:8009/v1/systemone";
|
|
3
|
+
export declare const KEV_SYSTEMONE_MODEL = "kev-latest";
|
|
4
|
+
export declare const DELEGATION_HINT_TIMEOUT_MS = 750;
|
|
5
|
+
type Tier = AutoroutingTier;
|
|
6
|
+
export interface DelegationHintMetrics {
|
|
7
|
+
toolCount: number;
|
|
8
|
+
editCount: number;
|
|
9
|
+
fileCount: number;
|
|
10
|
+
packageCount: number;
|
|
11
|
+
verificationCount: number;
|
|
12
|
+
consecutiveEdits: number;
|
|
13
|
+
/** Pending/in-progress peer tasks in the largest explicit plan phase. */
|
|
14
|
+
activePlanStepCount: number;
|
|
15
|
+
/** Remaining fraction of the context window, omitted when usage is unknown. */
|
|
16
|
+
remainingContextRatio?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface KevDecision {
|
|
19
|
+
noul: boolean;
|
|
20
|
+
pDelegate: number;
|
|
21
|
+
choice: Tier | null;
|
|
22
|
+
}
|
|
23
|
+
export type KevDecisionFetcher = (metrics: DelegationHintMetrics, choices: readonly Tier[], signal?: AbortSignal) => Promise<KevDecision | undefined>;
|
|
24
|
+
export type KevFetchImplementation = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
25
|
+
export interface DelegationHintOptions {
|
|
26
|
+
getMode: () => unknown;
|
|
27
|
+
getAutoroutingEnabled: () => unknown;
|
|
28
|
+
getAutoroutingTiers: () => unknown;
|
|
29
|
+
notify: (message: string) => void;
|
|
30
|
+
fetcher?: KevFetchImplementation;
|
|
31
|
+
}
|
|
32
|
+
/** Create a fixed-loopback, bounded Kev-compatible classifier client. */
|
|
33
|
+
export declare function createKevDecisionFetcher(fetchImplementation?: KevFetchImplementation): KevDecisionFetcher;
|
|
34
|
+
/** Ephemeral, bounded inference state. Notices stay out of prompts and session storage. */
|
|
35
|
+
export declare class DelegationHintController {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(options: DelegationHintOptions);
|
|
38
|
+
setEnabled(enabled: boolean): void;
|
|
39
|
+
/** Reset aggregate counters for the next assistant turn. */
|
|
40
|
+
onTurnStart(): void;
|
|
41
|
+
/** Prevent a pending classifier result from crossing into a new user prompt. */
|
|
42
|
+
onUserMessage(): void;
|
|
43
|
+
/** Synchronous callback; inference and its user-only notice never alter tool or model state. */
|
|
44
|
+
observeAfterToolCall(input: {
|
|
45
|
+
toolName: string;
|
|
46
|
+
args: Record<string, unknown>;
|
|
47
|
+
isError: boolean;
|
|
48
|
+
resultError?: boolean;
|
|
49
|
+
getActivePlanStepCount?: () => number;
|
|
50
|
+
getRemainingContextRatio?: () => number | undefined;
|
|
51
|
+
}, signal?: AbortSignal): void;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
package/examples/README.md
CHANGED
|
@@ -16,6 +16,6 @@ Example custom tools that extend the agent's capabilities.
|
|
|
16
16
|
## Documentation
|
|
17
17
|
|
|
18
18
|
- [SDK Reference](sdk/README.md)
|
|
19
|
-
- [Hooks Documentation](
|
|
20
|
-
- [Custom Tools Documentation](
|
|
21
|
-
- [Skills Documentation](
|
|
19
|
+
- [Hooks Documentation](../../../docs/hooks.md)
|
|
20
|
+
- [Custom Tools Documentation](../../../docs/codegraph-custom-tool.md#2-add-the-custom-tool)
|
|
21
|
+
- [Skills Documentation](../../../docs/skills.md)
|
|
@@ -40,7 +40,7 @@ Then in gjc:
|
|
|
40
40
|
|
|
41
41
|
## Writing Custom Tools
|
|
42
42
|
|
|
43
|
-
See [docs/custom-
|
|
43
|
+
See [docs/codegraph-custom-tool.md](../../../../docs/codegraph-custom-tool.md#2-add-the-custom-tool) for how tools are discovered and loaded.
|
|
44
44
|
|
|
45
45
|
### Key Points
|
|
46
46
|
|
package/examples/hooks/README.md
CHANGED
|
@@ -31,7 +31,7 @@ cp permission-gate.ts ~/.gjc/agent/hooks/
|
|
|
31
31
|
|
|
32
32
|
## Writing Hooks
|
|
33
33
|
|
|
34
|
-
See [docs/hooks.md](
|
|
34
|
+
See [docs/hooks.md](../../../../docs/hooks.md) for full documentation.
|
|
35
35
|
|
|
36
36
|
```typescript
|
|
37
37
|
import type { HookAPI } from "@gajae-code/coding-agent/hooks";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/coding-agent",
|
|
4
|
-
"version": "0.17.
|
|
4
|
+
"version": "0.17.7",
|
|
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",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
58
58
|
"@babel/parser": "^7.29.3",
|
|
59
59
|
"@mozilla/readability": "^0.6.0",
|
|
60
|
-
"@gajae-code/stats": "0.17.
|
|
61
|
-
"@gajae-code/agent-core": "0.17.
|
|
62
|
-
"@gajae-code/ai": "0.17.
|
|
63
|
-
"@gajae-code/natives": "0.17.
|
|
64
|
-
"@gajae-code/tui": "0.17.
|
|
65
|
-
"@gajae-code/utils": "0.17.
|
|
60
|
+
"@gajae-code/stats": "0.17.7",
|
|
61
|
+
"@gajae-code/agent-core": "0.17.7",
|
|
62
|
+
"@gajae-code/ai": "0.17.7",
|
|
63
|
+
"@gajae-code/natives": "0.17.7",
|
|
64
|
+
"@gajae-code/tui": "0.17.7",
|
|
65
|
+
"@gajae-code/utils": "0.17.7",
|
|
66
66
|
"@puppeteer/browsers": "^2.13.0",
|
|
67
67
|
"@types/turndown": "5.0.6",
|
|
68
68
|
"@xterm/headless": "^6.0.0",
|
|
@@ -119,6 +119,12 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
119
119
|
"agent_session:getPendingNextTurnMessagesForTests": "read-only test seam, not a user-facing SDK control seam",
|
|
120
120
|
"agent_session:queueCoordinatorRuntimeStatePersistForTests":
|
|
121
121
|
"test-only coordinator persistence ordering seam, not a user-facing SDK control seam",
|
|
122
|
+
"agent_session:trackCoordinatorRuntimeStatePersistenceFailuresForTests":
|
|
123
|
+
"test-only coordinator persistence failure observation seam, not a user-facing SDK control seam",
|
|
124
|
+
"agent_session:setCoordinatorRuntimeStateFileForTests":
|
|
125
|
+
"test-only coordinator runtime state file setup seam, not a user-facing SDK control seam",
|
|
126
|
+
"agent_session:getCoordinatorRuntimeStateFileForTests":
|
|
127
|
+
"read-only test-only coordinator runtime state file accessor, not a user-facing SDK control seam",
|
|
122
128
|
"agent_session:awaitCoordinatorRuntimeStatePersistenceForTests":
|
|
123
129
|
"test-only coordinator persistence drain barrier, not a user-facing SDK control seam",
|
|
124
130
|
"agent_session:parkAgentEndForCoordinatorPersistForTests":
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -101,6 +101,8 @@ function redactConfigValue(path: string, value: unknown, showSecrets?: boolean):
|
|
|
101
101
|
|
|
102
102
|
/** Find setting definition by path */
|
|
103
103
|
function findSettingDef(path: string): CliSettingDef | undefined {
|
|
104
|
+
if (path === "modelProfile.ownership") return undefined;
|
|
105
|
+
if (path === "modelProfile.default" && settings.getGlobal("modelProfile.ownership") !== undefined) return undefined;
|
|
104
106
|
if (!(path in SETTINGS_SCHEMA)) return undefined;
|
|
105
107
|
const key = path as SettingPath;
|
|
106
108
|
const ui = getUi(key);
|
|
@@ -98,8 +98,14 @@ export type PublicEvidenceStatus =
|
|
|
98
98
|
export const PUBLIC_COMMAND_DIAGNOSTICS = {
|
|
99
99
|
macos_nofile_limit_low:
|
|
100
100
|
"The macOS open-file limit is below the recommended minimum; increase it before starting additional concurrent work.",
|
|
101
|
+
sdk_resource_gone:
|
|
102
|
+
"The requested resource is not available from this session endpoint; this reports absent resource state, not an empty result.",
|
|
101
103
|
router_cleanup_failed: "SDK session Router cleanup failed.",
|
|
102
104
|
broker_cleanup_failed: "SDK broker client cleanup failed.",
|
|
105
|
+
// The broker reports this code from several distinct causes, so the text names none
|
|
106
|
+
// of them and never implies that another key would be safe.
|
|
107
|
+
lifecycle_idempotency_conflict:
|
|
108
|
+
"The broker reported an idempotency conflict. Reconcile existing lifecycle state before deciding whether another request is safe.",
|
|
103
109
|
usage_transport_exclusive: "Specify exactly one of --stdio or --socket <path>.",
|
|
104
110
|
usage_duplicate_option: "Each option on this command may occur at most once.",
|
|
105
111
|
usage_unknown_argument: "An unrecognized argument was supplied; re-read the command help for its accepted grammar.",
|