@oh-my-pi/pi-coding-agent 16.2.1 → 16.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +72 -0
- package/dist/cli.js +3621 -3579
- package/dist/types/advisor/__tests__/config.test.d.ts +1 -0
- package/dist/types/advisor/advise-tool.d.ts +8 -4
- package/dist/types/advisor/config.d.ts +88 -0
- package/dist/types/advisor/index.d.ts +1 -0
- package/dist/types/advisor/runtime.d.ts +15 -1
- package/dist/types/advisor/transcript-recorder.d.ts +13 -2
- package/dist/types/advisor/watchdog.d.ts +20 -0
- package/dist/types/collab/guest.d.ts +29 -0
- package/dist/types/config/model-roles.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +113 -12
- package/dist/types/debug/log-viewer.d.ts +1 -0
- package/dist/types/debug/raw-sse.d.ts +1 -0
- package/dist/types/discovery/omp-extension-roots.d.ts +3 -3
- package/dist/types/edit/hashline/diff.d.ts +0 -11
- package/dist/types/edit/index.d.ts +18 -0
- package/dist/types/edit/streaming.d.ts +30 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -0
- package/dist/types/extensibility/shared-events.d.ts +1 -0
- package/dist/types/extensibility/tool-event-input.d.ts +7 -0
- package/dist/types/extensibility/utils.d.ts +12 -0
- package/dist/types/mcp/oauth-discovery.d.ts +0 -11
- package/dist/types/mcp/transports/index.d.ts +1 -0
- package/dist/types/mcp/transports/sse.d.ts +20 -0
- package/dist/types/modes/components/advisor-config.d.ts +59 -0
- package/dist/types/modes/components/index.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +9 -1
- package/dist/types/modes/components/settings-selector.d.ts +1 -0
- package/dist/types/modes/components/status-line/component.d.ts +30 -3
- package/dist/types/modes/components/status-line/types.d.ts +13 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +10 -4
- package/dist/types/modes/skill-command.d.ts +32 -0
- package/dist/types/modes/types.d.ts +7 -2
- package/dist/types/sdk.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +84 -12
- package/dist/types/session/indexed-session-storage.d.ts +7 -1
- package/dist/types/session/messages.d.ts +32 -7
- package/dist/types/session/messages.test.d.ts +1 -0
- package/dist/types/session/session-entries.d.ts +31 -3
- package/dist/types/session/session-history-format.d.ts +6 -0
- package/dist/types/session/session-loader.d.ts +9 -1
- package/dist/types/session/session-manager.d.ts +6 -4
- package/dist/types/session/session-storage.d.ts +11 -0
- package/dist/types/session/session-title-slot.d.ts +19 -0
- package/dist/types/session/settings-stream-fn.d.ts +21 -0
- package/dist/types/session/turn-persistence.d.ts +88 -0
- package/dist/types/ssh/connection-manager.d.ts +47 -0
- package/dist/types/ssh/utils.d.ts +16 -0
- package/dist/types/task/executor.d.ts +3 -16
- package/dist/types/task/render.d.ts +0 -5
- package/dist/types/task/renderer.d.ts +13 -0
- package/dist/types/task/types.d.ts +16 -0
- package/dist/types/task/yield-assembly.d.ts +28 -0
- package/dist/types/tiny/text.d.ts +8 -0
- package/dist/types/tools/render-utils.d.ts +2 -0
- package/dist/types/tools/review.d.ts +6 -4
- package/dist/types/tools/ssh.d.ts +1 -1
- package/dist/types/tools/todo.d.ts +6 -0
- package/dist/types/tools/yield.d.ts +8 -3
- package/dist/types/utils/thinking-display.d.ts +4 -0
- package/package.json +12 -12
- package/src/advisor/__tests__/advisor.test.ts +438 -10
- package/src/advisor/__tests__/config.test.ts +173 -0
- package/src/advisor/advise-tool.ts +11 -6
- package/src/advisor/config.ts +256 -0
- package/src/advisor/index.ts +1 -0
- package/src/advisor/runtime.ts +77 -4
- package/src/advisor/transcript-recorder.ts +25 -2
- package/src/advisor/watchdog.ts +57 -31
- package/src/auto-thinking/classifier.ts +2 -2
- package/src/autoresearch/index.ts +7 -2
- package/src/cli/gc-cli.ts +17 -10
- package/src/collab/guest.ts +43 -7
- package/src/config/model-registry.ts +80 -18
- package/src/config/model-resolver.ts +5 -1
- package/src/config/model-roles.ts +3 -3
- package/src/config/settings-schema.ts +107 -8
- package/src/debug/index.ts +32 -7
- package/src/debug/log-viewer.ts +111 -53
- package/src/debug/raw-sse.ts +68 -48
- package/src/discovery/codex.ts +13 -5
- package/src/discovery/omp-extension-roots.ts +38 -13
- package/src/edit/hashline/diff.ts +57 -4
- package/src/edit/index.ts +21 -0
- package/src/edit/streaming.ts +170 -0
- package/src/eval/js/shared/local-module-loader.ts +23 -1
- package/src/export/html/template.js +13 -7
- package/src/extensibility/custom-tools/types.ts +1 -0
- package/src/extensibility/extensions/loader.ts +5 -3
- package/src/extensibility/extensions/wrapper.ts +9 -3
- package/src/extensibility/hooks/loader.ts +3 -3
- package/src/extensibility/hooks/tool-wrapper.ts +13 -4
- package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +18 -1
- package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +59 -2
- package/src/extensibility/plugins/manager.ts +76 -5
- package/src/extensibility/shared-events.ts +1 -0
- package/src/extensibility/tool-event-input.ts +23 -0
- package/src/extensibility/utils.ts +74 -0
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/mcp/client.ts +3 -1
- package/src/mcp/manager.ts +12 -5
- package/src/mcp/oauth-discovery.ts +5 -29
- package/src/mcp/transports/http.ts +3 -1
- package/src/mcp/transports/index.ts +1 -0
- package/src/mcp/transports/sse.ts +377 -0
- package/src/memories/index.ts +15 -6
- package/src/mnemopi/backend.ts +2 -2
- package/src/modes/acp/acp-agent.ts +1 -1
- package/src/modes/components/advisor-config.ts +555 -0
- package/src/modes/components/advisor-message.ts +9 -2
- package/src/modes/components/agent-hub.ts +9 -4
- package/src/modes/components/assistant-message.ts +5 -5
- package/src/modes/components/index.ts +2 -0
- package/src/modes/components/model-selector.ts +79 -48
- package/src/modes/components/settings-selector.ts +1 -0
- package/src/modes/components/status-line/component.ts +145 -14
- package/src/modes/components/status-line/segments.ts +47 -22
- package/src/modes/components/status-line/types.ts +13 -1
- package/src/modes/components/tool-execution.ts +47 -6
- package/src/modes/controllers/command-controller.ts +23 -2
- package/src/modes/controllers/event-controller.ts +114 -11
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +61 -61
- package/src/modes/controllers/selector-controller.ts +100 -9
- package/src/modes/interactive-mode.ts +65 -10
- package/src/modes/print-mode.ts +1 -1
- package/src/modes/skill-command.ts +116 -0
- package/src/modes/types.ts +7 -2
- package/src/modes/utils/transcript-render-helpers.ts +2 -2
- package/src/modes/utils/ui-helpers.ts +46 -27
- package/src/prompts/agents/reviewer.md +11 -10
- package/src/prompts/review-custom-request.md +1 -2
- package/src/prompts/review-request.md +1 -2
- package/src/prompts/system/interrupted-thinking.md +7 -0
- package/src/prompts/system/recap-user.md +9 -0
- package/src/prompts/system/subagent-system-prompt.md +8 -5
- package/src/prompts/system/subagent-yield-reminder.md +6 -5
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/prompts/tools/irc.md +2 -2
- package/src/prompts/tools/read.md +2 -2
- package/src/sdk.ts +40 -50
- package/src/session/agent-session.ts +1139 -600
- package/src/session/indexed-session-storage.ts +86 -13
- package/src/session/messages.test.ts +125 -0
- package/src/session/messages.ts +192 -21
- package/src/session/redis-session-storage.ts +49 -2
- package/src/session/session-entries.ts +39 -2
- package/src/session/session-history-format.ts +29 -2
- package/src/session/session-listing.ts +54 -24
- package/src/session/session-loader.ts +66 -3
- package/src/session/session-manager.ts +113 -19
- package/src/session/session-persistence.ts +96 -3
- package/src/session/session-storage.ts +36 -0
- package/src/session/session-title-slot.ts +141 -0
- package/src/session/settings-stream-fn.ts +49 -0
- package/src/session/sql-session-storage.ts +71 -11
- package/src/session/turn-persistence.ts +142 -0
- package/src/session/unexpected-stop-classifier.ts +2 -2
- package/src/slash-commands/builtin-registry.ts +16 -3
- package/src/slash-commands/helpers/mcp.ts +2 -1
- package/src/ssh/__tests__/connection-manager-args.test.ts +123 -1
- package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +55 -18
- package/src/ssh/connection-manager.ts +139 -12
- package/src/ssh/file-transfer.ts +23 -18
- package/src/ssh/ssh-executor.ts +2 -13
- package/src/ssh/utils.ts +19 -0
- package/src/task/executor.ts +21 -23
- package/src/task/render.ts +162 -20
- package/src/task/renderer.ts +14 -0
- package/src/task/types.ts +17 -0
- package/src/task/yield-assembly.ts +207 -0
- package/src/tiny/models.ts +8 -6
- package/src/tiny/text.ts +37 -7
- package/src/tools/ask.ts +55 -4
- package/src/tools/image-gen.ts +2 -1
- package/src/tools/render-utils.ts +2 -0
- package/src/tools/renderers.ts +8 -2
- package/src/tools/review.ts +17 -7
- package/src/tools/ssh.ts +8 -4
- package/src/tools/todo.ts +17 -1
- package/src/tools/tts.ts +2 -1
- package/src/tools/yield.ts +140 -31
- package/src/utils/thinking-display.ts +15 -0
- package/src/utils/title-generator.ts +1 -1
- package/src/web/search/providers/tavily.ts +36 -19
|
@@ -12,6 +12,32 @@ import type { OutputMeta } from "../tools/output-meta";
|
|
|
12
12
|
export declare const SKILL_PROMPT_MESSAGE_TYPE = "skill-prompt";
|
|
13
13
|
export declare const LSP_LATE_DIAGNOSTIC_MESSAGE_TYPE = "lsp-late-diagnostic";
|
|
14
14
|
export declare const BACKGROUND_TAN_DISPATCH_MESSAGE_TYPE = "background-tan-dispatch";
|
|
15
|
+
/** Custom message type for hidden interrupted-thinking continuity context. */
|
|
16
|
+
export declare const INTERRUPTED_THINKING_MESSAGE_TYPE = "interrupted-thinking";
|
|
17
|
+
/** Metadata persisted with a hidden interrupted-thinking continuity message. */
|
|
18
|
+
export interface InterruptedThinkingDetails {
|
|
19
|
+
interruptedAt: number;
|
|
20
|
+
provider: AssistantMessage["provider"];
|
|
21
|
+
model: string;
|
|
22
|
+
blockCount: number;
|
|
23
|
+
}
|
|
24
|
+
/** Pure helper result for persisting interrupted thinking outside the assistant turn. */
|
|
25
|
+
export interface DemotedInterruptedThinking {
|
|
26
|
+
reasoning: string;
|
|
27
|
+
strippedContent: AssistantMessage["content"];
|
|
28
|
+
blockCount: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Demote a trailing run of *incomplete* interrupted-thinking from an assistant
|
|
32
|
+
* message — reasoning that was still streaming when the user aborted.
|
|
33
|
+
*
|
|
34
|
+
* A block joins the run only when it is a non-empty `thinking` block with no
|
|
35
|
+
* `thinkingSignature`. A signed/complete thinking block (Anthropic signature,
|
|
36
|
+
* OpenAI reasoning item id) is safely replayable, so it ends the run and stays
|
|
37
|
+
* in place — as do `redactedThinking` encrypted blobs, text, tool calls,
|
|
38
|
+
* empty-thinking blocks, and trailing empty text placeholders.
|
|
39
|
+
*/
|
|
40
|
+
export declare function demoteInterruptedThinking(message: Pick<AssistantMessage, "content">): DemotedInterruptedThinking | undefined;
|
|
15
41
|
/** Details persisted on a `/tan` background-dispatch breadcrumb. */
|
|
16
42
|
export interface BackgroundTanDispatchDetails {
|
|
17
43
|
jobId: string;
|
|
@@ -43,18 +69,17 @@ export interface SkillPromptDetails {
|
|
|
43
69
|
* #buildTranscriptLines`, `runPrintMode`, and `AcpAgent#replayAssistantMessage`
|
|
44
70
|
* (fallback error emission) read it via `isSilentAbort`. */
|
|
45
71
|
export declare const SILENT_ABORT_MARKER = "__omp.silent_abort__";
|
|
46
|
-
/** Type-guard for
|
|
47
|
-
*
|
|
48
|
-
|
|
49
|
-
export declare function isSilentAbort(errorMessage: string | undefined): boolean;
|
|
72
|
+
/** Type-guard for silent aborts. Renderers MUST call this helper so structured
|
|
73
|
+
* `errorId` and legacy persisted marker messages stay in lockstep. */
|
|
74
|
+
export declare function isSilentAbort(message: Pick<AssistantMessage, "errorId" | "errorMessage">): boolean;
|
|
50
75
|
/** Reason threaded through `AbortController.abort(reason)` when the user aborts
|
|
51
76
|
* the turn with Esc (see `AgentSession.abort`). The agent keeps it on the
|
|
52
77
|
* aborted assistant message's `errorMessage` so queued follow-ups/tool-result
|
|
53
78
|
* placeholders can distinguish a deliberate interrupt from a bare lifecycle
|
|
54
79
|
* abort, but interactive renderers suppress this redundant transcript line. */
|
|
55
80
|
export declare const USER_INTERRUPT_LABEL = "Interrupted by user";
|
|
56
|
-
export declare function isUserInterruptAbort(
|
|
57
|
-
export declare function shouldRenderAbortReason(
|
|
81
|
+
export declare function isUserInterruptAbort(message: Pick<AssistantMessage, "errorId" | "errorMessage">): boolean;
|
|
82
|
+
export declare function shouldRenderAbortReason(message: Pick<AssistantMessage, "errorId" | "errorMessage">): boolean;
|
|
58
83
|
/** Sentinel `errorMessage` the agent stamps on any abort that carried no custom
|
|
59
84
|
* reason (bare `abort()`). Renderers treat it as "no specific reason given". */
|
|
60
85
|
export declare const GENERIC_ABORT_SENTINEL = "Request was aborted";
|
|
@@ -63,7 +88,7 @@ export declare const GENERIC_ABORT_SENTINEL = "Request was aborted";
|
|
|
63
88
|
* no threaded reason fall back to the retry-aware generic label. Call
|
|
64
89
|
* `shouldRenderAbortReason` before rendering when user interrupts should stay
|
|
65
90
|
* visually quiet. */
|
|
66
|
-
export declare function resolveAbortLabel(
|
|
91
|
+
export declare function resolveAbortLabel(message: Pick<AssistantMessage, "errorId" | "errorMessage">, retryAttempt?: number): string;
|
|
67
92
|
/** Extract the optional `__queueChipText` field from a CustomMessage's
|
|
68
93
|
* `details` blob. Safe over `unknown`; returns undefined when the field is
|
|
69
94
|
* absent or non-string. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { ImageContent, MessageAttribution, ServiceTier, TextContent } from "@oh-my-pi/pi-ai";
|
|
3
3
|
export declare const CURRENT_SESSION_VERSION = 3;
|
|
4
|
+
export declare const SESSION_TITLE_SLOT_BYTES = 256;
|
|
5
|
+
export declare const SESSION_TITLE_SLOT_ENTRY_TYPE = "title";
|
|
6
|
+
export declare const TITLE_CHANGE_ENTRY_TYPE = "title_change";
|
|
7
|
+
export type SessionTitleSource = "auto" | "user";
|
|
8
|
+
/** Fixed-width first-line slot carrying the mutable current session title. */
|
|
9
|
+
export interface SessionTitleSlotEntry {
|
|
10
|
+
type: typeof SESSION_TITLE_SLOT_ENTRY_TYPE;
|
|
11
|
+
v: 1;
|
|
12
|
+
title: string;
|
|
13
|
+
source?: SessionTitleSource;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
pad: string;
|
|
16
|
+
}
|
|
4
17
|
export declare const EPHEMERAL_MODEL_CHANGE_ROLE = "fallback";
|
|
5
18
|
export interface SessionHeader {
|
|
6
19
|
type: "session";
|
|
7
20
|
version?: number;
|
|
8
21
|
id: string;
|
|
9
22
|
title?: string;
|
|
10
|
-
titleSource?:
|
|
23
|
+
titleSource?: SessionTitleSource;
|
|
11
24
|
timestamp: string;
|
|
12
25
|
cwd: string;
|
|
13
26
|
parentSession?: string;
|
|
@@ -91,6 +104,19 @@ export interface LabelEntry extends SessionEntryBase {
|
|
|
91
104
|
targetId: string;
|
|
92
105
|
label: string | undefined;
|
|
93
106
|
}
|
|
107
|
+
/** Append-only audit entry recording a session title change. */
|
|
108
|
+
export interface TitleChangeEntry extends SessionEntryBase {
|
|
109
|
+
type: typeof TITLE_CHANGE_ENTRY_TYPE;
|
|
110
|
+
title: string;
|
|
111
|
+
previousTitle?: string;
|
|
112
|
+
source: SessionTitleSource;
|
|
113
|
+
trigger?: string;
|
|
114
|
+
}
|
|
115
|
+
declare module "@oh-my-pi/pi-agent-core/compaction/entries" {
|
|
116
|
+
interface CustomCompactionSessionEntries {
|
|
117
|
+
titleChange: TitleChangeEntry;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
94
120
|
/** TTSR injection entry - tracks which time-traveling rules have been injected this session. */
|
|
95
121
|
export interface TtsrInjectionEntry extends SessionEntryBase {
|
|
96
122
|
type: "ttsr_injection";
|
|
@@ -149,9 +175,11 @@ export interface CustomMessageEntry<T = unknown> extends SessionEntryBase {
|
|
|
149
175
|
attribution?: MessageAttribution;
|
|
150
176
|
}
|
|
151
177
|
/** Session entry - has id/parentId for tree structure (returned by "read" methods in SessionManager) */
|
|
152
|
-
export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TtsrInjectionEntry | MCPToolSelectionEntry | SessionInitEntry | ModeChangeEntry;
|
|
153
|
-
/** Raw file entry
|
|
178
|
+
export type SessionEntry = SessionMessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | ServiceTierChangeEntry | CompactionEntry | BranchSummaryEntry | CustomEntry | CustomMessageEntry | LabelEntry | TitleChangeEntry | TtsrInjectionEntry | MCPToolSelectionEntry | SessionInitEntry | ModeChangeEntry;
|
|
179
|
+
/** Raw logical file entry after loaders strip any fixed-width title slot. */
|
|
154
180
|
export type FileEntry = SessionHeader | SessionEntry;
|
|
181
|
+
/** Physical JSONL entry before slot-aware loaders fold the title slot. */
|
|
182
|
+
export type RawFileEntry = SessionTitleSlotEntry | FileEntry;
|
|
155
183
|
/** Tree node for getTree() - defensive copy of session structure */
|
|
156
184
|
export interface SessionTreeNode {
|
|
157
185
|
entry: SessionEntry;
|
|
@@ -18,6 +18,12 @@ export interface HistoryFormatOptions {
|
|
|
18
18
|
* still collapse to a one-liner.
|
|
19
19
|
*/
|
|
20
20
|
expandPrimaryContext?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Append the full unified diff (from a tool result's `details.diff`) below
|
|
23
|
+
* edit/apply_patch tool lines, instead of just the path. The advisor sets
|
|
24
|
+
* this so it sees what changed without re-reading the file.
|
|
25
|
+
*/
|
|
26
|
+
expandEditDiffs?: boolean;
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* Hidden custom messages that inject the primary agent's operative *constraints*
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import { BlobStore } from "./blob-store";
|
|
3
|
-
import type
|
|
3
|
+
import { type FileEntry, type SessionTitleSlotEntry } from "./session-entries";
|
|
4
4
|
import { type SessionStorage } from "./session-storage";
|
|
5
|
+
import { type SessionTitleUpdate } from "./session-title-slot";
|
|
6
|
+
/** Parse session JSONL while stripping and folding the optional fixed title slot. */
|
|
7
|
+
export declare function parseSessionContent(content: string): {
|
|
8
|
+
entries: FileEntry[];
|
|
9
|
+
titleSlot: SessionTitleUpdate | undefined;
|
|
10
|
+
};
|
|
11
|
+
/** Read only the fixed-size head window to detect a physical title slot. */
|
|
12
|
+
export declare function readTitleSlotFromFile(filePath: string, storage?: SessionStorage): Promise<SessionTitleSlotEntry | undefined>;
|
|
5
13
|
/** Exported for compaction.test.ts */
|
|
6
14
|
export declare function parseSessionEntries(content: string): FileEntry[];
|
|
7
15
|
/** Exported for testing */
|
|
@@ -3,7 +3,7 @@ import { ArtifactManager } from "./artifacts";
|
|
|
3
3
|
import { type BlobPutOptions, type BlobPutResult } from "./blob-store";
|
|
4
4
|
import { type BashExecutionMessage, type CustomMessage, type FileMentionMessage, type HookMessage, type PythonExecutionMessage } from "./messages";
|
|
5
5
|
import { type BuildSessionContextOptions, type SessionContext } from "./session-context";
|
|
6
|
-
import { type NewSessionOptions, type SessionEntry, type SessionHeader, type SessionTreeNode, type UsageStatistics } from "./session-entries";
|
|
6
|
+
import { type NewSessionOptions, type SessionEntry, type SessionHeader, type SessionTitleSource, type SessionTreeNode, type UsageStatistics } from "./session-entries";
|
|
7
7
|
import { type SessionInfo } from "./session-listing";
|
|
8
8
|
import { type SessionStorage } from "./session-storage";
|
|
9
9
|
export type ReadonlySessionManager = Pick<SessionManager, "getCwd" | "getSessionDir" | "getSessionId" | "getSessionFile" | "getSessionName" | "getArtifactsDir" | "getArtifactManager" | "allocateArtifactPath" | "saveArtifact" | "getArtifactPath" | "getLeafId" | "getLeafEntry" | "getEntry" | "getLabel" | "getBranch" | "getHeader" | "getEntries" | "getTree" | "getUsageStatistics" | "putBlob" | "putBlobSync">;
|
|
@@ -12,8 +12,10 @@ interface SessionManagerStateSnapshot {
|
|
|
12
12
|
sessionDir: string;
|
|
13
13
|
sessionId: string;
|
|
14
14
|
sessionName: string | undefined;
|
|
15
|
-
titleSource:
|
|
15
|
+
titleSource: SessionTitleSource | undefined;
|
|
16
16
|
sessionFile: string | undefined;
|
|
17
|
+
titleUpdatedAt: string;
|
|
18
|
+
hasTitleSlot: boolean;
|
|
17
19
|
onDisk: boolean;
|
|
18
20
|
needsRewrite: boolean;
|
|
19
21
|
header: SessionHeader;
|
|
@@ -109,7 +111,7 @@ export declare class SessionManager {
|
|
|
109
111
|
saveDraft(text: string): Promise<void>;
|
|
110
112
|
consumeDraft(): Promise<string | null>;
|
|
111
113
|
/** The source that set the session name: "user" (manual/RPC) or "auto" (generated title). */
|
|
112
|
-
get titleSource():
|
|
114
|
+
get titleSource(): SessionTitleSource | undefined;
|
|
113
115
|
getSessionName(): string | undefined;
|
|
114
116
|
onSessionNameChanged(cb: () => void): () => void;
|
|
115
117
|
/**
|
|
@@ -117,7 +119,7 @@ export declare class SessionManager {
|
|
|
117
119
|
* @param source "user" for explicit renames; "auto" for generated titles.
|
|
118
120
|
* Auto titles are ignored once the user has set a name.
|
|
119
121
|
*/
|
|
120
|
-
setSessionName(name: string, source?:
|
|
122
|
+
setSessionName(name: string, source?: SessionTitleSource, trigger?: string): Promise<boolean>;
|
|
121
123
|
/**
|
|
122
124
|
* Append a foreign (host-authored) entry verbatim, preserving its
|
|
123
125
|
* `id`/`parentId`. Used by collab guests to mirror the host session.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SessionTitleUpdate } from "./session-title-slot";
|
|
1
2
|
export interface SessionStorageStat {
|
|
2
3
|
size: number;
|
|
3
4
|
mtimeMs: number;
|
|
@@ -22,6 +23,14 @@ export interface SessionStorage {
|
|
|
22
23
|
ensureDirSync(dir: string): void;
|
|
23
24
|
existsSync(path: string): boolean;
|
|
24
25
|
writeTextSync(path: string, content: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Update the current session title through the storage backend.
|
|
28
|
+
*
|
|
29
|
+
* File-like backends rewrite the fixed-width JSONL title slot; indexed
|
|
30
|
+
* backends can store the semantic title fields and synthesize the slot when
|
|
31
|
+
* reading.
|
|
32
|
+
*/
|
|
33
|
+
updateSessionTitle(path: string, update: SessionTitleUpdate): Promise<void>;
|
|
25
34
|
statSync(path: string): SessionStorageStat;
|
|
26
35
|
listFilesSync(dir: string, pattern: string): string[];
|
|
27
36
|
exists(path: string): Promise<boolean>;
|
|
@@ -43,6 +52,7 @@ export declare class FileSessionStorage implements SessionStorage {
|
|
|
43
52
|
ensureDirSync(dir: string): void;
|
|
44
53
|
existsSync(path: string): boolean;
|
|
45
54
|
writeTextSync(fpath: string, content: string): void;
|
|
55
|
+
updateSessionTitle(fpath: string, update: SessionTitleUpdate): Promise<void>;
|
|
46
56
|
statSync(path: string): SessionStorageStat;
|
|
47
57
|
listFilesSync(dir: string, pattern: string): string[];
|
|
48
58
|
exists(path: string): Promise<boolean>;
|
|
@@ -67,6 +77,7 @@ export declare class MemorySessionStorage implements SessionStorage {
|
|
|
67
77
|
ensureDirSync(_dir: string): void;
|
|
68
78
|
existsSync(path: string): boolean;
|
|
69
79
|
writeTextSync(path: string, content: string): void;
|
|
80
|
+
updateSessionTitle(path: string, update: SessionTitleUpdate): Promise<void>;
|
|
70
81
|
/**
|
|
71
82
|
* Internal O(1) append used by {@link MemorySessionStorageWriter}. Lazily
|
|
72
83
|
* creates the entry. External callers should go through `openWriter()`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SessionTitleSlotEntry, type SessionTitleSource } from "./session-entries";
|
|
2
|
+
/** Semantic title update persisted by session storage backends. */
|
|
3
|
+
export interface SessionTitleUpdate {
|
|
4
|
+
title?: string;
|
|
5
|
+
source?: SessionTitleSource;
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
}
|
|
8
|
+
/** Parse a physical title slot JSONL line. Returns undefined for legacy headers. */
|
|
9
|
+
export declare function parseTitleSlotLine(line: string): SessionTitleSlotEntry | undefined;
|
|
10
|
+
/** Parse the fixed-width title slot from a physical session body. */
|
|
11
|
+
export declare function parseTitleSlotFromContent(content: string): SessionTitleSlotEntry | undefined;
|
|
12
|
+
/** Convert a parsed title slot to the semantic storage update shape. */
|
|
13
|
+
export declare function titleUpdateFromSlot(slot: SessionTitleSlotEntry | undefined): SessionTitleUpdate | undefined;
|
|
14
|
+
/** Serialize the fixed-width first-line title slot, exactly 256 UTF-8 bytes including newline. */
|
|
15
|
+
export declare function serializeTitleSlot(options: SessionTitleUpdate): string;
|
|
16
|
+
/** Replace the physical fixed-width title slot in a full session body. */
|
|
17
|
+
export declare function overlayTitleSlotContent(content: string, update: SessionTitleUpdate): string;
|
|
18
|
+
/** Replace the physical fixed-width title slot in a prefix byte window. */
|
|
19
|
+
export declare function overlayTitleSlotPrefix(prefix: string, prefixBytes: number, update: SessionTitleUpdate): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings-aware stream wrapper shared by the main agent (sdk.ts) and the
|
|
3
|
+
* advisor agent (AgentSession.#buildAdvisorRuntime).
|
|
4
|
+
*
|
|
5
|
+
* Reads OpenRouter / Antigravity routing variants, Responses-family text
|
|
6
|
+
* verbosity, per-provider in-flight caps, and the loop guard out of `Settings`
|
|
7
|
+
* per request, layering them onto whatever options the caller passed. Before
|
|
8
|
+
* this helper existed, advisor turns called bare `streamSimple` while the main
|
|
9
|
+
* turn went through an inline closure that read these settings — so an advisor on
|
|
10
|
+
* OpenRouter never saw `providers.openrouterVariant`, breaking sticky routing
|
|
11
|
+
* and OpenRouter response-cache hits across advisor calls.
|
|
12
|
+
*/
|
|
13
|
+
import type { StreamFn } from "@oh-my-pi/pi-agent-core";
|
|
14
|
+
import { type Settings } from "../config/settings";
|
|
15
|
+
/**
|
|
16
|
+
* Build a {@link StreamFn} that reads provider routing/guard settings from
|
|
17
|
+
* `settings` per call and forwards to `base` (defaults to `streamSimple`).
|
|
18
|
+
*
|
|
19
|
+
* Caller-supplied `streamOptions` always win — the helper only fills holes.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createSettingsAwareStreamFn(settings: Settings, base?: StreamFn): StreamFn;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers that share one cheap, structural identity for messages — both during
|
|
3
|
+
* incremental persistence and for the mid-run-compaction ordering check.
|
|
4
|
+
*
|
|
5
|
+
* Previously `AgentSession` carried two near-duplicate routines
|
|
6
|
+
* (`#sessionMessagesReferToSameTurn` + `#messageValueSignature`) that
|
|
7
|
+
* reconstructed the branch path on every check (O(n²) `unshift`) and
|
|
8
|
+
* `JSON.stringify`-compared the full message content on every pairwise hit.
|
|
9
|
+
* Long-running sessions with many subagents fired this thousands of times per
|
|
10
|
+
* minute and froze the TUI loop (see issue #3629). The persistence key already
|
|
11
|
+
* encodes a stable logical identity — timestamp + role-specific discriminators
|
|
12
|
+
* — so the structural compare is now the rare collision tiebreaker (e.g. two
|
|
13
|
+
* provider responses at the same millisecond with `undefined` responseId),
|
|
14
|
+
* not the load-bearing check.
|
|
15
|
+
*
|
|
16
|
+
* The helpers here keep that identity in one place and expose the planner so
|
|
17
|
+
* the persistence-ordering logic is unit-testable without standing up an
|
|
18
|
+
* `AgentSession`.
|
|
19
|
+
*/
|
|
20
|
+
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
21
|
+
/**
|
|
22
|
+
* Stable identity for messages that pass through {@link AgentSession}'s
|
|
23
|
+
* incremental persistence path.
|
|
24
|
+
*
|
|
25
|
+
* The discriminators chosen per role are precisely the fields that uniquely
|
|
26
|
+
* identify a single logical message instance:
|
|
27
|
+
*
|
|
28
|
+
* - `assistant` — timestamp + provider + model + responseId + stopReason
|
|
29
|
+
* (responseId is the canonical provider-side id when available; the rest
|
|
30
|
+
* disambiguate when it is not, e.g. local/dev models).
|
|
31
|
+
* - `toolResult` — timestamp + toolCallId + toolName (toolCallId is unique
|
|
32
|
+
* per execution; toolName guards against synthetic reuse).
|
|
33
|
+
* - `user` / `developer` — timestamp + attribution (attribution distinguishes
|
|
34
|
+
* user-typed vs hook-injected at the same wall-clock millisecond).
|
|
35
|
+
* - `fileMention` — timestamp.
|
|
36
|
+
*
|
|
37
|
+
* Returns `undefined` for message roles that are not persisted through this
|
|
38
|
+
* path (e.g. `hookMessage`, `custom`, `bashExecution`) — those follow other
|
|
39
|
+
* append paths in `SessionManager`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function sessionMessagePersistenceKey(message: AgentMessage): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Slow-path content equality check used when two messages collide on
|
|
44
|
+
* {@link sessionMessagePersistenceKey}. Only the role's content fields are
|
|
45
|
+
* compared (no timestamps, no metadata) because the key already pinned all of
|
|
46
|
+
* those down.
|
|
47
|
+
*
|
|
48
|
+
* Most calls into the persistence path never reach this — keys are unique
|
|
49
|
+
* enough in production that the snapshot lookup short-circuits at the key
|
|
50
|
+
* level. Restoring the structural compare here preserves the pre-#3629
|
|
51
|
+
* contract that two messages with the same metadata BUT different content are
|
|
52
|
+
* distinct (e.g. two assistant turns with `undefined` responseId emitted in
|
|
53
|
+
* the same wall-clock millisecond, which is exactly how the in-memory test
|
|
54
|
+
* harness crafts streamed responses).
|
|
55
|
+
*/
|
|
56
|
+
export declare function sameMessageContent(left: AgentMessage, right: AgentMessage): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Outcome of {@link planTurnPersistence}.
|
|
59
|
+
*
|
|
60
|
+
* `ok` lists the turn-message indices that still need to be appended (in
|
|
61
|
+
* order). `out-of-order` reports the first message whose later sibling is
|
|
62
|
+
* already persisted — the caller bails so it does not silently splice a
|
|
63
|
+
* stale message between newer entries on the live branch.
|
|
64
|
+
*/
|
|
65
|
+
export type TurnPersistencePlan = {
|
|
66
|
+
kind: "ok";
|
|
67
|
+
toPersist: readonly number[];
|
|
68
|
+
} | {
|
|
69
|
+
kind: "out-of-order";
|
|
70
|
+
messageIndex: number;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Decide what to do with a turn's messages relative to what's already on the
|
|
74
|
+
* branch, in a single pass over the pre-computed keys.
|
|
75
|
+
*
|
|
76
|
+
* @param turnKeys persistence keys for each turn message, in the order the
|
|
77
|
+
* agent loop emitted them. `undefined` slots represent messages with no
|
|
78
|
+
* persistence key (skipped silently).
|
|
79
|
+
* @param persistedKeys the snapshot of persistence keys currently on the
|
|
80
|
+
* branch (built once per call from {@link sessionMessagePersistenceKey} for
|
|
81
|
+
* each persisted message entry).
|
|
82
|
+
*
|
|
83
|
+
* The check is O(n²) over turn messages — but `n` here is the size of one
|
|
84
|
+
* turn (a handful of tool results), not the size of the branch. That's the
|
|
85
|
+
* point of this refactor: the expensive O(branch) work happens exactly once,
|
|
86
|
+
* inside the caller's snapshot loop, not per-comparison.
|
|
87
|
+
*/
|
|
88
|
+
export declare function planTurnPersistence(turnKeys: readonly (string | undefined)[], persistedKeys: ReadonlySet<string>): TurnPersistencePlan;
|
|
@@ -14,6 +14,15 @@ export interface SSHHostInfo {
|
|
|
14
14
|
version: number;
|
|
15
15
|
os: SSHHostOs;
|
|
16
16
|
shell: SSHHostShell;
|
|
17
|
+
/**
|
|
18
|
+
* Shell name OMP verified can execute the POSIX transfer snippets
|
|
19
|
+
* (`head`/`cat`/`mv`/`test`/`ls`) `ssh://` uses. Probed by running
|
|
20
|
+
* `sh -lc` / `bash -lc` / `zsh -lc` against the remote and keeping the
|
|
21
|
+
* first one that round-trips a known marker. Independent of `shell`
|
|
22
|
+
* (the self-reported login shell), which may be noisy, exotic, or simply
|
|
23
|
+
* mis-classified — only `transferShell` gates ssh:// transfers.
|
|
24
|
+
*/
|
|
25
|
+
transferShell?: "sh" | "bash" | "zsh";
|
|
17
26
|
compatShell?: "bash" | "sh";
|
|
18
27
|
compatEnabled: boolean;
|
|
19
28
|
}
|
|
@@ -22,6 +31,44 @@ interface SSHArgsOptions {
|
|
|
22
31
|
/** When true, omit `-n` so the remote command can read from our piped stdin. */
|
|
23
32
|
allowStdin?: boolean;
|
|
24
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse a raw cache-file value (or any unknown) into a normalized
|
|
36
|
+
* {@link SSHHostInfo}, dropping fields that don't pass the per-field guards.
|
|
37
|
+
* Exported so cache-layer round-tripping (incl. the new `transferShell`
|
|
38
|
+
* field, #3719) is testable without touching disk.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseHostInfo(value: unknown): SSHHostInfo | null;
|
|
41
|
+
/**
|
|
42
|
+
* Frame marker emitted by the remote OS/shell probe. The probe wraps its
|
|
43
|
+
* payload in this prefix so the parser can ignore startup-file noise (banners,
|
|
44
|
+
* `motd`, login messages, `Last login: …`) instead of trusting only the first
|
|
45
|
+
* line of stdout. See #3719.
|
|
46
|
+
*/
|
|
47
|
+
export declare const HOST_PROBE_MARKER = "PI_HOST_PROBE=";
|
|
48
|
+
/** Marker for the transfer-shell capability probe. */
|
|
49
|
+
export declare const TRANSFER_PROBE_MARKER = "PI_TRANSFER_OK|";
|
|
50
|
+
/**
|
|
51
|
+
* Find the first line of `stdout`/`stderr` that begins with `marker` and
|
|
52
|
+
* return everything after it. Used by the SSH host probe so noisy login
|
|
53
|
+
* dotfiles can't corrupt OS/shell classification by emitting text on the
|
|
54
|
+
* first line of `ssh` output.
|
|
55
|
+
*
|
|
56
|
+
* Returns `null` when no marker line is found in either stream.
|
|
57
|
+
*/
|
|
58
|
+
export declare function extractProbePayload(stdout: string, stderr: string, marker?: string): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Find `marker` anywhere in `stdout` or `stderr` and return everything that
|
|
61
|
+
* follows it, scanning stdout first. Returns `null` when the marker is in
|
|
62
|
+
* neither stream.
|
|
63
|
+
*
|
|
64
|
+
* Used by the transfer-shell capability probe. Some remotes have broken
|
|
65
|
+
* login dotfiles that swap fd 1/2, so the marker can land on stderr even
|
|
66
|
+
* though the probe ran the printf successfully (matches the host-info
|
|
67
|
+
* probe's stderr fallback). See #3719.
|
|
68
|
+
*/
|
|
69
|
+
export declare function findProbeMarker(stdout: string, stderr: string, marker: string): string | null;
|
|
70
|
+
/** Classify a POSIX-ish `uname -s` payload from the transfer-shell probe. */
|
|
71
|
+
export declare function osFromUname(value: string): SSHHostOs | undefined;
|
|
25
72
|
export declare function getHostInfo(hostName: string): Promise<SSHHostInfo | undefined>;
|
|
26
73
|
export declare function getHostInfoForHost(host: SSHConnectionTarget): Promise<SSHHostInfo | undefined>;
|
|
27
74
|
/**
|
|
@@ -6,3 +6,19 @@ export declare function buildSshTarget(username: string | undefined, host: strin
|
|
|
6
6
|
* `ssh://` file-transfer helpers.
|
|
7
7
|
*/
|
|
8
8
|
export declare function quotePosixPath(value: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Wrap a POSIX command in `<shell> -c '<command>'` so it runs under the
|
|
11
|
+
* named shell rather than whatever `$SHELL` happens to be on the remote.
|
|
12
|
+
*
|
|
13
|
+
* Used by the `ssh://` transfer helpers and the Windows compat dispatch:
|
|
14
|
+
* OpenSSH passes our snippets to `<login-shell> -c`, so a remote whose
|
|
15
|
+
* login shell is fish/csh/tcsh (or cmd/powershell on Windows compat)
|
|
16
|
+
* can't parse `if [ … ]; then …`. Wrapping forces parsing under the
|
|
17
|
+
* shell OMP actually verified can run the snippet.
|
|
18
|
+
*
|
|
19
|
+
* `-c` (not `-lc`): the transfer snippets only call absolute POSIX
|
|
20
|
+
* builtins (`head`/`cat`/`mv`/`test`/`ls`/`mkdir`/`rm`/`dirname`) and
|
|
21
|
+
* don't need login-profile setup. Capability *probing* still uses
|
|
22
|
+
* `-lc` to mirror the user's real environment.
|
|
23
|
+
*/
|
|
24
|
+
export declare function wrapInPosixShell(shell: "sh" | "bash" | "zsh", command: string): string;
|
|
@@ -23,7 +23,8 @@ import type { AuthStorage } from "../session/auth-storage";
|
|
|
23
23
|
import type { ContextFileEntry } from "../tools";
|
|
24
24
|
import type { EventBus } from "../utils/event-bus";
|
|
25
25
|
import type { WorkspaceTree } from "../workspace-tree";
|
|
26
|
-
import { type AgentDefinition, type AgentProgress, type ReviewFinding, type SingleResult } from "./types";
|
|
26
|
+
import { type AgentDefinition, type AgentProgress, type ReviewFinding, type SingleResult, type YieldItem } from "./types";
|
|
27
|
+
export type { YieldItem } from "./types";
|
|
27
28
|
/**
|
|
28
29
|
* Soft per-agent request budgets (assistant requests per run). When a subagent
|
|
29
30
|
* crosses its budget it receives ONE steering notice asking it to wrap up; at
|
|
@@ -164,20 +165,6 @@ export interface ExecutorOptions {
|
|
|
164
165
|
*/
|
|
165
166
|
keepAlive?: boolean;
|
|
166
167
|
}
|
|
167
|
-
export interface YieldItem {
|
|
168
|
-
data?: unknown;
|
|
169
|
-
status?: "success" | "aborted";
|
|
170
|
-
error?: string;
|
|
171
|
-
/**
|
|
172
|
-
* Set by the in-tool yield validator when it exhausted its retry budget
|
|
173
|
-
* (MAX_SCHEMA_RETRIES) and accepted a schema-invalid payload anyway.
|
|
174
|
-
* `finalizeSubprocessOutput` honors this by serializing the payload and
|
|
175
|
-
* surfacing a stderr warning, instead of re-emitting `schema_violation`
|
|
176
|
-
* — which would silently swap the subagent's "accepted" view for a
|
|
177
|
-
* different, opaque error blob in the parent's view of the result.
|
|
178
|
-
*/
|
|
179
|
-
schemaOverridden?: boolean;
|
|
180
|
-
}
|
|
181
168
|
interface FinalizeSubprocessOutputArgs {
|
|
182
169
|
rawOutput: string;
|
|
183
170
|
exitCode: number;
|
|
@@ -187,6 +174,7 @@ interface FinalizeSubprocessOutputArgs {
|
|
|
187
174
|
yieldItems?: YieldItem[];
|
|
188
175
|
reportFindings?: ReviewFinding[];
|
|
189
176
|
outputSchema: unknown;
|
|
177
|
+
lastAssistantText?: string;
|
|
190
178
|
}
|
|
191
179
|
interface FinalizeSubprocessOutputResult {
|
|
192
180
|
rawOutput: string;
|
|
@@ -217,4 +205,3 @@ export declare function finalizeSubagentLifecycle(args: {
|
|
|
217
205
|
* Run a single agent in-process.
|
|
218
206
|
*/
|
|
219
207
|
export declare function runSubprocess(options: ExecutorOptions): Promise<SingleResult>;
|
|
220
|
-
export {};
|
|
@@ -31,9 +31,4 @@ export declare function renderResult(result: {
|
|
|
31
31
|
details?: TaskToolDetails;
|
|
32
32
|
isError?: boolean;
|
|
33
33
|
}, options: TaskRenderOptions, theme: Theme, args?: TaskParams): Component;
|
|
34
|
-
export declare const taskToolRenderer: {
|
|
35
|
-
renderCall: typeof renderCall;
|
|
36
|
-
renderResult: typeof renderResult;
|
|
37
|
-
mergeCallAndResult: boolean;
|
|
38
|
-
};
|
|
39
34
|
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task tool renderer export.
|
|
3
|
+
*
|
|
4
|
+
* Separated from render.ts to avoid circular dependency issues with
|
|
5
|
+
* tools/renderers.ts. This module has no side effects and can be safely
|
|
6
|
+
* imported without triggering the subprocessToolRegistry registration.
|
|
7
|
+
*/
|
|
8
|
+
import { renderCall, renderResult } from "./render";
|
|
9
|
+
export declare const taskToolRenderer: {
|
|
10
|
+
readonly renderCall: typeof renderCall;
|
|
11
|
+
readonly renderResult: typeof renderResult;
|
|
12
|
+
readonly mergeCallAndResult: true;
|
|
13
|
+
};
|
|
@@ -206,6 +206,22 @@ export interface AgentDefinition {
|
|
|
206
206
|
source: AgentSource;
|
|
207
207
|
filePath?: string;
|
|
208
208
|
}
|
|
209
|
+
/** Details extracted from a subagent `yield` tool call for final-result assembly and task rendering. */
|
|
210
|
+
export interface YieldItem {
|
|
211
|
+
data?: unknown;
|
|
212
|
+
status?: "success" | "aborted";
|
|
213
|
+
error?: string;
|
|
214
|
+
/** A string label is terminal; a non-empty array of labels is incremental. */
|
|
215
|
+
type?: string | string[];
|
|
216
|
+
/** Resolve this yield's payload from the latest durable assistant text instead of `data`. */
|
|
217
|
+
useLastTurn?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Set by the in-tool yield validator when it exhausted its retry budget and
|
|
220
|
+
* accepted schema-invalid data anyway. The executor preserves that override
|
|
221
|
+
* during post-mortem validation.
|
|
222
|
+
*/
|
|
223
|
+
schemaOverridden?: boolean;
|
|
224
|
+
}
|
|
209
225
|
/** Progress tracking for a single agent */
|
|
210
226
|
export interface AgentProgress {
|
|
211
227
|
index: number;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { YieldItem } from "./types";
|
|
2
|
+
/** Outcome of folding a run's yield calls into one payload, with provenance flags. */
|
|
3
|
+
interface AssembledYieldResult {
|
|
4
|
+
data: unknown;
|
|
5
|
+
schemaOverridden: boolean;
|
|
6
|
+
rawText: boolean;
|
|
7
|
+
missingData: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Top-level output-schema property names declared as arrays (JTD `elements` →
|
|
11
|
+
* JSON `type: "array"`). An incremental yield section for such a label
|
|
12
|
+
* accumulates into a list even when the agent emits exactly one — otherwise a
|
|
13
|
+
* single `type: ["findings"]` yield would assemble as a bare object and fail
|
|
14
|
+
* array-typed schema validation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function arrayValuedLabels(outputSchema: unknown): ReadonlySet<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Assemble typed yield calls into the final payload consumed by schema validation.
|
|
19
|
+
*
|
|
20
|
+
* A non-empty array `type` contributes an incremental section and never decides
|
|
21
|
+
* termination by itself. A string `type` with omitted `data` makes the last
|
|
22
|
+
* assistant turn the raw terminal result. Other string-typed yields contribute
|
|
23
|
+
* the terminal labelled section. Untyped terminal yields keep the historical
|
|
24
|
+
* "last yield wins" behavior unless no terminal yield exists, in which case
|
|
25
|
+
* accumulated typed sections finalize on idle.
|
|
26
|
+
*/
|
|
27
|
+
export declare function assembleYieldResult(yieldItems: YieldItem[], lastAssistantText?: string, arrayLabels?: ReadonlySet<string>): AssembledYieldResult | undefined;
|
|
28
|
+
export {};
|
|
@@ -16,6 +16,14 @@ export declare function stripCodeBlocks(message: string): string;
|
|
|
16
16
|
/** Prepare a raw user message for titling: drop code blocks, then bound length. */
|
|
17
17
|
export declare function prepareTitleInput(message: string): string;
|
|
18
18
|
export declare function formatTitleUserMessage(message: string): string;
|
|
19
|
+
/** Single recent conversation turn supplied to title refresh after replanning. */
|
|
20
|
+
export interface TitleConversationTurn {
|
|
21
|
+
role: "user" | "assistant";
|
|
22
|
+
text?: string;
|
|
23
|
+
thinking?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Format recent user/assistant context for title generation after a todo replan. */
|
|
26
|
+
export declare function formatTitleConversationContext(turns: readonly TitleConversationTurn[]): string;
|
|
19
27
|
/**
|
|
20
28
|
* True when a first user message is too low-signal to title (greeting, ack,
|
|
21
29
|
* bare number, or empty once code/punctuation/emoji are stripped).
|
|
@@ -45,6 +45,8 @@ export declare const TRUNCATE_LENGTHS: {
|
|
|
45
45
|
readonly LINE: 110;
|
|
46
46
|
/** Very short (task previews, badges) */
|
|
47
47
|
readonly SHORT: 40;
|
|
48
|
+
/** Idle recap status line (~40-word LLM reply) */
|
|
49
|
+
readonly RECAP: 280;
|
|
48
50
|
};
|
|
49
51
|
/** Human-readable key currently bound to tool-output expansion, e.g. `Ctrl+O`. */
|
|
50
52
|
export declare function expandKeyHint(): string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Legacy hidden review-finding tool for agents that have not migrated to
|
|
3
|
+
* incremental `yield` sections.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Hidden by default - only enabled when explicitly listed in an agent's tools.
|
|
6
|
+
* Reviewers now finish via incremental `yield`; this tool remains for
|
|
7
|
+
* compatibility with older or custom review agents.
|
|
7
8
|
*/
|
|
8
9
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
9
10
|
import type { Theme, ThemeColor } from "../modes/theme/theme";
|
|
@@ -15,6 +16,7 @@ export interface FindingPriorityInfo {
|
|
|
15
16
|
color: ThemeColor;
|
|
16
17
|
}
|
|
17
18
|
export declare const PRIORITY_LABELS: FindingPriority[];
|
|
19
|
+
export declare function isFindingPriority(value: unknown): value is FindingPriority;
|
|
18
20
|
export declare function getPriorityInfo(priority: FindingPriority): FindingPriorityInfo;
|
|
19
21
|
declare const ReportFindingParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
20
22
|
title: string;
|
|
@@ -67,7 +67,7 @@ export declare const sshToolRenderer: {
|
|
|
67
67
|
renderContext?: SshRenderContext;
|
|
68
68
|
}, uiTheme: Theme, args?: SshRenderArgs): Component;
|
|
69
69
|
mergeCallAndResult: boolean;
|
|
70
|
-
provisionalPendingPreview:
|
|
70
|
+
provisionalPendingPreview: boolean;
|
|
71
71
|
provisionalPartialResult: boolean;
|
|
72
72
|
};
|
|
73
73
|
export {};
|