@oh-my-pi/pi-coding-agent 15.1.2 → 15.1.4
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 +60 -0
- package/dist/types/async/job-manager.d.ts +3 -2
- package/dist/types/cli/auth-broker-cli.d.ts +25 -0
- package/dist/types/cli/auth-gateway-cli.d.ts +18 -0
- package/dist/types/cli/grievances-cli.d.ts +12 -0
- package/dist/types/commands/auth-broker.d.ts +54 -0
- package/dist/types/commands/auth-gateway.d.ts +32 -0
- package/dist/types/commands/grievances.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-commit.d.ts +9 -1
- package/dist/types/commit/agentic/tools/schemas.d.ts +9 -1
- package/dist/types/commit/agentic/tools/split-commit.d.ts +9 -1
- package/dist/types/config/model-registry.d.ts +3 -0
- package/dist/types/config/models-config-schema.d.ts +1 -0
- package/dist/types/config/settings-schema.d.ts +46 -0
- package/dist/types/discovery/agents.d.ts +12 -1
- package/dist/types/edit/renderer.d.ts +3 -0
- package/dist/types/eval/index.d.ts +0 -2
- package/dist/types/goals/tools/goal-tool.d.ts +10 -2
- package/dist/types/index.d.ts +0 -1
- package/dist/types/internal-urls/index.d.ts +1 -1
- package/dist/types/internal-urls/{pi-protocol.d.ts → omp-protocol.d.ts} +3 -3
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/main.d.ts +11 -2
- package/dist/types/modes/acp/acp-agent.d.ts +2 -1
- package/dist/types/modes/acp/acp-event-mapper.d.ts +13 -1
- package/dist/types/modes/acp/acp-mode.d.ts +3 -1
- package/dist/types/modes/emoji-autocomplete.d.ts +16 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +4 -0
- package/dist/types/plan-mode/approved-plan.d.ts +10 -4
- package/dist/types/sdk.d.ts +10 -3
- package/dist/types/session/agent-session.d.ts +7 -3
- package/dist/types/session/auth-broker-config.d.ts +13 -0
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/client-bridge.d.ts +3 -0
- package/dist/types/tools/eval.d.ts +41 -7
- package/dist/types/tools/irc.d.ts +8 -2
- package/dist/types/tools/report-tool-issue.d.ts +118 -1
- package/dist/types/tools/resolve.d.ts +8 -2
- package/examples/custom-tools/README.md +3 -12
- package/examples/extensions/README.md +2 -15
- package/examples/extensions/api-demo.ts +1 -7
- package/package.json +7 -7
- package/src/async/job-manager.ts +111 -13
- package/src/autoresearch/tools/init-experiment.ts +11 -33
- package/src/autoresearch/tools/log-experiment.ts +10 -24
- package/src/autoresearch/tools/run-experiment.ts +1 -1
- package/src/autoresearch/tools/update-notes.ts +2 -9
- package/src/cli/auth-broker-cli.ts +746 -0
- package/src/cli/auth-gateway-cli.ts +342 -0
- package/src/cli/grievances-cli.ts +109 -16
- package/src/cli/update-cli.ts +1 -5
- package/src/cli.ts +4 -2
- package/src/commands/auth-broker.ts +96 -0
- package/src/commands/auth-gateway.ts +61 -0
- package/src/commands/grievances.ts +13 -8
- package/src/commands/launch.ts +1 -1
- package/src/commit/agentic/agent.ts +2 -0
- package/src/commit/agentic/tools/analyze-file.ts +2 -2
- package/src/commit/agentic/tools/git-file-diff.ts +2 -2
- package/src/commit/agentic/tools/git-hunk.ts +3 -3
- package/src/commit/agentic/tools/git-overview.ts +2 -2
- package/src/commit/agentic/tools/propose-changelog.ts +1 -3
- package/src/commit/agentic/tools/recent-commits.ts +1 -1
- package/src/commit/agentic/tools/schemas.ts +1 -9
- package/src/config/model-equivalence.ts +279 -174
- package/src/config/model-registry.ts +37 -6
- package/src/config/model-resolver.ts +13 -8
- package/src/config/models-config-schema.ts +8 -0
- package/src/config/settings-schema.ts +52 -0
- package/src/cursor.ts +1 -1
- package/src/debug/log-formatting.ts +1 -1
- package/src/debug/log-viewer.ts +1 -1
- package/src/debug/profiler.ts +4 -0
- package/src/debug/raw-sse-buffer.ts +100 -59
- package/src/debug/raw-sse.ts +1 -1
- package/src/discovery/agents.ts +15 -4
- package/src/edit/modes/apply-patch.ts +1 -5
- package/src/edit/modes/patch.ts +5 -5
- package/src/edit/modes/replace.ts +5 -5
- package/src/edit/renderer.ts +2 -1
- package/src/edit/streaming.ts +1 -1
- package/src/eval/index.ts +0 -2
- package/src/eval/js/shared/runtime.ts +107 -2
- package/src/eval/py/kernel.ts +1 -1
- package/src/exa/researcher.ts +4 -4
- package/src/exa/search.ts +10 -22
- package/src/exa/websets.ts +33 -33
- package/src/extensibility/typebox.ts +44 -17
- package/src/goals/tools/goal-tool.ts +3 -3
- package/src/index.ts +0 -3
- package/src/internal-urls/docs-index.generated.ts +21 -18
- package/src/internal-urls/index.ts +1 -1
- package/src/internal-urls/{pi-protocol.ts → omp-protocol.ts} +10 -10
- package/src/internal-urls/router.ts +3 -3
- package/src/internal-urls/types.ts +1 -1
- package/src/lsp/types.ts +8 -11
- package/src/main.ts +216 -146
- package/src/mcp/tool-bridge.ts +3 -3
- package/src/modes/acp/acp-agent.ts +203 -57
- package/src/modes/acp/acp-client-bridge.ts +2 -1
- package/src/modes/acp/acp-event-mapper.ts +208 -32
- package/src/modes/acp/acp-mode.ts +11 -3
- package/src/modes/components/bash-execution.ts +1 -1
- package/src/modes/components/diff.ts +1 -2
- package/src/modes/components/eval-execution.ts +1 -1
- package/src/modes/components/oauth-selector.ts +38 -2
- package/src/modes/components/tool-execution.ts +1 -2
- package/src/modes/components/tree-selector.ts +26 -7
- package/src/modes/controllers/command-controller.ts +95 -34
- package/src/modes/controllers/input-controller.ts +4 -3
- package/src/modes/data/emojis.json +1 -0
- package/src/modes/emoji-autocomplete.ts +285 -0
- package/src/modes/interactive-mode.ts +92 -19
- package/src/modes/print-mode.ts +3 -3
- package/src/modes/prompt-action-autocomplete.ts +14 -0
- package/src/plan-mode/approved-plan.ts +30 -9
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/ttsr-tool-reminder.md +5 -0
- package/src/prompts/tools/ask.md +4 -3
- package/src/prompts/tools/eval.md +25 -26
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/resolve.md +1 -1
- package/src/prompts/tools/search.md +1 -1
- package/src/prompts/tools/web-search.md +1 -1
- package/src/sdk.ts +81 -8
- package/src/session/agent-session.ts +362 -131
- package/src/session/agent-storage.ts +7 -2
- package/src/session/auth-broker-config.ts +102 -0
- package/src/session/auth-storage.ts +7 -1
- package/src/session/client-bridge.ts +3 -0
- package/src/session/streaming-output.ts +1 -1
- package/src/task/types.ts +10 -35
- package/src/tools/bash-interactive.ts +4 -1
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser.ts +12 -20
- package/src/tools/eval.ts +77 -100
- package/src/tools/gh.ts +21 -45
- package/src/tools/hindsight-recall.ts +1 -1
- package/src/tools/hindsight-reflect.ts +2 -2
- package/src/tools/hindsight-retain.ts +3 -7
- package/src/tools/index.ts +8 -1
- package/src/tools/inspect-image.ts +4 -1
- package/src/tools/irc.ts +4 -12
- package/src/tools/job.ts +3 -11
- package/src/tools/report-tool-issue.ts +462 -17
- package/src/tools/resolve.ts +2 -7
- package/src/tools/todo-write.ts +8 -15
- package/src/utils/title-generator.ts +3 -0
- package/src/web/search/index.ts +6 -6
- package/dist/types/eval/parse.d.ts +0 -28
- package/dist/types/eval/sniff.d.ts +0 -11
- package/src/eval/eval.lark +0 -36
- package/src/eval/parse.ts +0 -407
- package/src/eval/sniff.ts +0 -28
|
@@ -7,14 +7,20 @@ export interface PlanApprovalDetails {
|
|
|
7
7
|
title: string;
|
|
8
8
|
planExists: boolean;
|
|
9
9
|
}
|
|
10
|
-
/** Validate the agent-supplied plan title
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
/** Validate and normalize the agent-supplied plan title into a safe filename stem.
|
|
11
|
+
* Spaces and other URL-safe punctuation are replaced with hyphens so models that
|
|
12
|
+
* produce natural-language titles (e.g. "My feature plan") still succeed.
|
|
13
|
+
* Characters that cannot be safely represented after replacement are dropped.
|
|
14
|
+
* The result is restricted to letters, numbers, underscores, and hyphens so it
|
|
15
|
+
* is safe to splice into a `local://` URL without escaping. */
|
|
14
16
|
export declare function normalizePlanTitle(title: string): {
|
|
15
17
|
title: string;
|
|
16
18
|
fileName: string;
|
|
17
19
|
};
|
|
20
|
+
/** Humanize a normalized plan title for use as a session display name.
|
|
21
|
+
* Replaces `-`/`_` separators with spaces and capitalizes the first letter.
|
|
22
|
+
* Returns an empty string when the input collapses to whitespace. */
|
|
23
|
+
export declare function humanizePlanTitle(title: string): string;
|
|
18
24
|
interface RenameApprovedPlanFileOptions {
|
|
19
25
|
planFilePath: string;
|
|
20
26
|
finalPlanFilePath: string;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AgentTelemetryConfig, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type
|
|
2
|
+
import { type Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { type Rule } from "./capability/rule";
|
|
4
4
|
import { ModelRegistry } from "./config/model-registry";
|
|
5
5
|
import { type PromptTemplate } from "./config/prompt-templates";
|
|
@@ -153,8 +153,15 @@ export type { Tool } from "./tools";
|
|
|
153
153
|
export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "./workspace-tree";
|
|
154
154
|
export { BashTool, BUILTIN_TOOLS, createTools, EditTool, EvalTool, FindTool, HIDDEN_TOOLS, loadSshTool, ReadTool, ResolveTool, SearchTool, type ToolSession, WebSearchTool, WriteTool, };
|
|
155
155
|
/**
|
|
156
|
-
* Create an AuthStorage instance
|
|
157
|
-
*
|
|
156
|
+
* Create an AuthStorage instance.
|
|
157
|
+
*
|
|
158
|
+
* Default: local SQLite store at `<agentDir>/agent.db`.
|
|
159
|
+
*
|
|
160
|
+
* Broker mode: when `OMP_AUTH_BROKER_URL` is set, credentials are pulled from
|
|
161
|
+
* a remote auth-broker over the wire. Refresh tokens never leave the broker;
|
|
162
|
+
* the client receives access tokens with `refresh = "__remote__"` and calls
|
|
163
|
+
* back into the broker through the {@link AuthStorageOptions.refreshOAuthCredential}
|
|
164
|
+
* override to re-mint access tokens when needed.
|
|
158
165
|
*/
|
|
159
166
|
export declare function discoverAuthStorage(agentDir?: string): Promise<AuthStorage>;
|
|
160
167
|
/**
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { type Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentTool, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
16
16
|
import { type CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
17
17
|
import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolChoice, UsageReport } from "@oh-my-pi/pi-ai";
|
|
18
|
-
import { type AsyncJob, AsyncJobManager } from "../async";
|
|
18
|
+
import { type AsyncJob, type AsyncJobDeliveryState, AsyncJobManager } from "../async";
|
|
19
19
|
import type { Rule } from "../capability/rule";
|
|
20
20
|
import { type ModelRegistry } from "../config/model-registry";
|
|
21
21
|
import { type ResolvedModelRoleValue } from "../config/model-resolver";
|
|
@@ -111,6 +111,7 @@ export type AsyncJobSnapshotItem = Pick<AsyncJob, "id" | "type" | "status" | "la
|
|
|
111
111
|
export interface AsyncJobSnapshot {
|
|
112
112
|
running: AsyncJobSnapshotItem[];
|
|
113
113
|
recent: AsyncJobSnapshotItem[];
|
|
114
|
+
delivery: AsyncJobDeliveryState;
|
|
114
115
|
}
|
|
115
116
|
export interface AgentSessionConfig {
|
|
116
117
|
agent: Agent;
|
|
@@ -347,6 +348,9 @@ export declare class AgentSession {
|
|
|
347
348
|
get isStreaming(): boolean;
|
|
348
349
|
/** Wait until streaming and deferred recovery work are fully settled. */
|
|
349
350
|
waitForIdle(): Promise<void>;
|
|
351
|
+
drainAsyncJobDeliveriesForAcp(options?: {
|
|
352
|
+
timeoutMs?: number;
|
|
353
|
+
}): Promise<boolean>;
|
|
350
354
|
/** Most recent assistant message in agent state. */
|
|
351
355
|
getLastAssistantMessage(): AssistantMessage | undefined;
|
|
352
356
|
/** Current effective system prompt blocks (includes any per-turn extension modifications) */
|
|
@@ -495,7 +499,7 @@ export declare class AgentSession {
|
|
|
495
499
|
*
|
|
496
500
|
* Handles three cases:
|
|
497
501
|
* - Streaming: queue as steer/follow-up or store for next turn
|
|
498
|
-
* - Not streaming + triggerTurn: appends to state/session, starts new turn
|
|
502
|
+
* - Not streaming + triggerTurn: appends to state/session, starts new turn unless the client cannot own it
|
|
499
503
|
* - Not streaming + no trigger: appends to state/session, no turn
|
|
500
504
|
*/
|
|
501
505
|
sendCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: {
|
|
@@ -855,7 +859,7 @@ export declare class AgentSession {
|
|
|
855
859
|
* otherwise estimates tokens for all messages.
|
|
856
860
|
*/
|
|
857
861
|
getContextUsage(): ContextUsage | undefined;
|
|
858
|
-
fetchUsageReports(): Promise<UsageReport[] | null>;
|
|
862
|
+
fetchUsageReports(signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
859
863
|
/**
|
|
860
864
|
* Export session to HTML.
|
|
861
865
|
* @param outputPath Optional output path (defaults to session directory)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface AuthBrokerClientConfig {
|
|
2
|
+
url: string;
|
|
3
|
+
token: string;
|
|
4
|
+
}
|
|
5
|
+
/** Path to the local bearer token file. Created on the broker host by `omp auth-broker token`. */
|
|
6
|
+
export declare function getAuthBrokerTokenFilePath(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Read broker configuration. Returns null when the URL is missing
|
|
9
|
+
* (broker disabled — local store is used). Throws when URL is set but no
|
|
10
|
+
* token is available — the caller cannot fall back silently because the
|
|
11
|
+
* user explicitly asked to use the broker.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveAuthBrokerConfig(): Promise<AuthBrokerClientConfig | null>;
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* All credential storage types and the AuthStorage class now live in the ai package.
|
|
4
4
|
*/
|
|
5
5
|
export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, OAuthCredential, SerializedAuthStorage, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
|
|
6
|
-
export { AuthStorage } from "@oh-my-pi/pi-ai";
|
|
6
|
+
export { AuthBrokerClient, AuthStorage, REMOTE_REFRESH_SENTINEL, RemoteAuthCredentialStore, SqliteAuthCredentialStore, } from "@oh-my-pi/pi-ai";
|
|
@@ -23,6 +23,7 @@ export interface ClientBridgePermissionToolCall {
|
|
|
23
23
|
toolName: string;
|
|
24
24
|
title: string;
|
|
25
25
|
kind?: string;
|
|
26
|
+
status?: "pending" | "in_progress" | "completed" | "failed";
|
|
26
27
|
rawInput?: unknown;
|
|
27
28
|
locations?: {
|
|
28
29
|
path: string;
|
|
@@ -70,6 +71,8 @@ export interface ClientBridgeCreateTerminalParams {
|
|
|
70
71
|
}
|
|
71
72
|
export interface ClientBridge {
|
|
72
73
|
readonly capabilities: ClientBridgeCapabilities;
|
|
74
|
+
/** ACP v1 clients cannot show server-initiated turns as busy after prompt response. */
|
|
75
|
+
readonly deferAgentInitiatedTurns?: boolean;
|
|
73
76
|
readTextFile?(params: {
|
|
74
77
|
path: string;
|
|
75
78
|
line?: number;
|
|
@@ -6,8 +6,32 @@ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
|
6
6
|
import { type Theme } from "../modes/theme/theme";
|
|
7
7
|
import { type ToolSession } from ".";
|
|
8
8
|
export declare const EVAL_DEFAULT_PREVIEW_LINES = 10;
|
|
9
|
+
/**
|
|
10
|
+
* Per-cell input. Each cell runs in order; state persists within a language
|
|
11
|
+
* across cells and across tool calls.
|
|
12
|
+
*/
|
|
13
|
+
declare const evalCellSchema: z.ZodObject<{
|
|
14
|
+
language: z.ZodEnum<{
|
|
15
|
+
js: "js";
|
|
16
|
+
py: "py";
|
|
17
|
+
}>;
|
|
18
|
+
code: z.ZodString;
|
|
19
|
+
title: z.ZodOptional<z.ZodString>;
|
|
20
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
reset: z.ZodOptional<z.ZodBoolean>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
export type EvalCellInput = z.infer<typeof evalCellSchema>;
|
|
9
24
|
export declare const evalSchema: z.ZodObject<{
|
|
10
|
-
|
|
25
|
+
cells: z.ZodArray<z.ZodObject<{
|
|
26
|
+
language: z.ZodEnum<{
|
|
27
|
+
js: "js";
|
|
28
|
+
py: "py";
|
|
29
|
+
}>;
|
|
30
|
+
code: z.ZodString;
|
|
31
|
+
title: z.ZodOptional<z.ZodString>;
|
|
32
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
reset: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
}, z.core.$strip>>;
|
|
11
35
|
}, z.core.$strip>;
|
|
12
36
|
export type EvalToolParams = z.infer<typeof evalSchema>;
|
|
13
37
|
export type EvalToolResult = {
|
|
@@ -35,20 +59,30 @@ export declare class EvalTool implements AgentTool<typeof evalSchema> {
|
|
|
35
59
|
readonly label = "Eval";
|
|
36
60
|
get description(): string;
|
|
37
61
|
readonly parameters: z.ZodObject<{
|
|
38
|
-
|
|
62
|
+
cells: z.ZodArray<z.ZodObject<{
|
|
63
|
+
language: z.ZodEnum<{
|
|
64
|
+
js: "js";
|
|
65
|
+
py: "py";
|
|
66
|
+
}>;
|
|
67
|
+
code: z.ZodString;
|
|
68
|
+
title: z.ZodOptional<z.ZodString>;
|
|
69
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
reset: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
39
72
|
}, z.core.$strip>;
|
|
40
73
|
readonly concurrency = "exclusive";
|
|
41
74
|
readonly strict = true;
|
|
42
75
|
readonly intent: (args: Partial<z.infer<typeof evalSchema>>) => string | undefined;
|
|
43
|
-
get customFormat(): {
|
|
44
|
-
syntax: "lark";
|
|
45
|
-
definition: string;
|
|
46
|
-
};
|
|
47
76
|
constructor(session: ToolSession | null, options?: EvalToolOptions);
|
|
48
77
|
execute(_toolCallId: string, params: z.infer<typeof evalSchema>, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback, _ctx?: AgentToolContext): Promise<AgentToolResult<EvalToolDetails | undefined>>;
|
|
49
78
|
}
|
|
79
|
+
interface EvalRenderCellArg {
|
|
80
|
+
language?: string;
|
|
81
|
+
code?: string;
|
|
82
|
+
title?: string;
|
|
83
|
+
}
|
|
50
84
|
interface EvalRenderArgs {
|
|
51
|
-
|
|
85
|
+
cells?: EvalRenderCellArg[];
|
|
52
86
|
__partialJson?: string;
|
|
53
87
|
}
|
|
54
88
|
interface EvalRenderContext {
|
|
@@ -21,7 +21,10 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
|
|
|
21
21
|
import * as z from "zod/v4";
|
|
22
22
|
import type { ToolSession } from ".";
|
|
23
23
|
declare const ircSchema: z.ZodObject<{
|
|
24
|
-
op: z.
|
|
24
|
+
op: z.ZodEnum<{
|
|
25
|
+
list: "list";
|
|
26
|
+
send: "send";
|
|
27
|
+
}>;
|
|
25
28
|
to: z.ZodOptional<z.ZodString>;
|
|
26
29
|
message: z.ZodOptional<z.ZodString>;
|
|
27
30
|
awaitReply: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -59,7 +62,10 @@ export declare class IrcTool implements AgentTool<typeof ircSchema, IrcDetails>
|
|
|
59
62
|
readonly summary = "Send and receive messages between agents over IRC-like channels";
|
|
60
63
|
readonly description: string;
|
|
61
64
|
readonly parameters: z.ZodObject<{
|
|
62
|
-
op: z.
|
|
65
|
+
op: z.ZodEnum<{
|
|
66
|
+
list: "list";
|
|
67
|
+
send: "send";
|
|
68
|
+
}>;
|
|
63
69
|
to: z.ZodOptional<z.ZodString>;
|
|
64
70
|
message: z.ZodOptional<z.ZodString>;
|
|
65
71
|
awaitReply: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1,6 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* report_tool_issue — automated QA tool for tracking unexpected tool behavior.
|
|
3
|
+
*
|
|
4
|
+
* Enabled by default; gated behind PI_AUTO_QA=1 / `dev.autoqa` so a user
|
|
5
|
+
* who flips the setting off short-circuits injection entirely.
|
|
6
|
+
* Always injected into every agent (including subagents) regardless of tool selection.
|
|
7
|
+
* Records grievances to a local SQLite database; never throws.
|
|
8
|
+
*
|
|
9
|
+
* Before the first record lands, the user's consent is checked. If they've
|
|
10
|
+
* never been asked (`dev.autoqa.consent === "unset"`) the process-global
|
|
11
|
+
* consent handler — wired by `InteractiveMode` to a Yes/No popup — is
|
|
12
|
+
* invoked exactly once and the decision is persisted. Subsequent calls
|
|
13
|
+
* (including from subagents) read the cached decision without prompting.
|
|
14
|
+
*
|
|
15
|
+
* When the user grants consent, push is automatically active against the
|
|
16
|
+
* bundled endpoint (`dev.autoqaPush.endpoint`, default `qa.omp.sh`). Each
|
|
17
|
+
* insert schedules a background flush that POSTs pending rows and deletes
|
|
18
|
+
* them on HTTP 2xx. `PI_AUTO_QA_PUSH=1` forces push in non-interactive
|
|
19
|
+
* environments where the consent dialog never fires. Tool execution is
|
|
20
|
+
* never blocked on the network and never throws.
|
|
21
|
+
*/
|
|
22
|
+
import { Database } from "bun:sqlite";
|
|
1
23
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
24
|
import type { Settings } from "..";
|
|
3
25
|
import type { ToolSession } from "./index";
|
|
4
26
|
export declare function isAutoQaEnabled(settings?: Settings): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Resolver for the user's "share grievances?" consent.
|
|
29
|
+
*
|
|
30
|
+
* Return values:
|
|
31
|
+
* - `true` — user agreed; record + ship for this run and persist.
|
|
32
|
+
* - `false` — user declined; suppress for this run and persist.
|
|
33
|
+
* - `null` — user dismissed the dialog (ESC, click-away, …) without
|
|
34
|
+
* picking an option. The decision is NOT cached or persisted,
|
|
35
|
+
* so the next `report_tool_issue` invocation re-prompts.
|
|
36
|
+
*
|
|
37
|
+
* Persistence is the tool's job (so subagent invocations can persist into
|
|
38
|
+
* the disk-backed `Settings` instance the host registered alongside the
|
|
39
|
+
* handler), not the handler's. Implementations live in hosts that have UI
|
|
40
|
+
* affordances — today only `InteractiveMode`. When no handler is
|
|
41
|
+
* registered (CLI subcommands, tests, non-interactive runs) consent
|
|
42
|
+
* defaults to `false` — the explicit "don't collect by default" stance.
|
|
43
|
+
*/
|
|
44
|
+
export type AutoQaConsentHandler = () => Promise<boolean | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Register the consent handler and the persistent {@link Settings} instance
|
|
47
|
+
* the decision should be written to. Passing `null` clears the handler
|
|
48
|
+
* (e.g. on `InteractiveMode` teardown). Re-registration is authoritative.
|
|
49
|
+
*/
|
|
50
|
+
export declare function setAutoQaConsentHandler(handler: AutoQaConsentHandler | null, persistentSettings?: Settings | null): void;
|
|
51
|
+
/** Test-only: clear consent cache + handler. Never call from production code. */
|
|
52
|
+
export declare function __resetAutoQaConsentForTests(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the user's consent for `report_tool_issue` grievances.
|
|
55
|
+
*
|
|
56
|
+
* Precedence (highest first):
|
|
57
|
+
* 1. Process-global cache (set on first successful resolution).
|
|
58
|
+
* 2. Persistent setting (`dev.autoqa.consent` on the supplied `Settings`).
|
|
59
|
+
* 3. Persistent setting on the registered host `Settings`.
|
|
60
|
+
* 4. Consent handler popup (single-flight; persists the answer).
|
|
61
|
+
* 5. Default-deny when no handler is registered.
|
|
62
|
+
*
|
|
63
|
+
* Never throws — handler errors degrade to "denied for this call" without
|
|
64
|
+
* caching, so a subsequent invocation can re-prompt instead of being
|
|
65
|
+
* permanently locked into the false branch.
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveAutoQaConsent(settings: Settings | undefined): Promise<boolean>;
|
|
5
68
|
export declare function getAutoQaDbPath(): string;
|
|
6
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Open (or return the cached handle for) the auto-QA SQLite database at
|
|
71
|
+
* `~/.omp/agent/autoqa.db`. Idempotently runs schema creation, the
|
|
72
|
+
* `pushed`-column migration, and index setup so every consumer — tool
|
|
73
|
+
* execute path, manual `omp grievances push`, future debug scripts —
|
|
74
|
+
* sees the same prepared schema. Returns `null` only on a hard open
|
|
75
|
+
* failure (filesystem permissions, etc.); a missing file is created.
|
|
76
|
+
*
|
|
77
|
+
* Exported because the `omp grievances` CLI handlers need the migrated
|
|
78
|
+
* handle too — having a second `openDb` in the CLI led to the column
|
|
79
|
+
* never being added on the manual-push path.
|
|
80
|
+
*/
|
|
81
|
+
export declare function openAutoQaDb(): Database | null;
|
|
82
|
+
export interface FlushResult {
|
|
83
|
+
pushed: number;
|
|
84
|
+
ok: boolean;
|
|
85
|
+
skipped?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Optional per-flush controls. Used by `omp grievances push` to surface
|
|
89
|
+
* progress to a TTY and to skip the user-facing consent gate (manual
|
|
90
|
+
* pushes are the user's explicit intent, not a side effect of a tool call).
|
|
91
|
+
*/
|
|
92
|
+
export interface FlushOptions {
|
|
93
|
+
/**
|
|
94
|
+
* Skip the `dev.autoqa.consent === "granted"` gate in
|
|
95
|
+
* {@link resolvePushConfig}. Endpoint configuration is still required.
|
|
96
|
+
* Reserved for explicit user-driven pushes (CLI `grievances push`,
|
|
97
|
+
* future debug recipes); never set from the tool's auto-flush path.
|
|
98
|
+
*/
|
|
99
|
+
bypassConsent?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Fires once at the start of the loop with the snapshot count of
|
|
102
|
+
* unpushed rows. Subsequent inserts won't be reflected (the count is
|
|
103
|
+
* a planning hint for progress reporters, not a live total).
|
|
104
|
+
*/
|
|
105
|
+
onStart?: (totalUnpushed: number) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Fires after every successfully shipped batch with the running pushed
|
|
108
|
+
* count. Reporters compare against the `totalUnpushed` they saw in
|
|
109
|
+
* `onStart` to advance their bar.
|
|
110
|
+
*/
|
|
111
|
+
onProgress?: (pushedSoFar: number) => void;
|
|
112
|
+
}
|
|
113
|
+
/** Test-only: clear single-flight + cooldown state. Never call from production code. */
|
|
114
|
+
export declare function __resetAutoQaFlushStateForTests(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Flush queued grievances to the configured backend.
|
|
117
|
+
*
|
|
118
|
+
* Single-flight: concurrent callers share the in-flight promise. After a
|
|
119
|
+
* failed push, retries are skipped for {@link FAILURE_COOLDOWN_MS} ms.
|
|
120
|
+
* Never throws — all errors are caught and routed to the logger.
|
|
121
|
+
*/
|
|
122
|
+
export declare function flushGrievances(db?: Database, settings?: Settings, options?: FlushOptions): Promise<FlushResult>;
|
|
123
|
+
export declare function createReportToolIssueTool(session: ToolSession, activeBuiltinNames?: readonly string[]): AgentTool;
|
|
@@ -5,7 +5,10 @@ import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
|
5
5
|
import type { Theme } from "../modes/theme/theme";
|
|
6
6
|
import type { ToolSession } from ".";
|
|
7
7
|
declare const resolveSchema: z.ZodObject<{
|
|
8
|
-
action: z.
|
|
8
|
+
action: z.ZodEnum<{
|
|
9
|
+
apply: "apply";
|
|
10
|
+
discard: "discard";
|
|
11
|
+
}>;
|
|
9
12
|
reason: z.ZodString;
|
|
10
13
|
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
11
14
|
}, z.core.$strip>;
|
|
@@ -54,7 +57,10 @@ export declare class ResolveTool implements AgentTool<typeof resolveSchema, Reso
|
|
|
54
57
|
readonly hidden = true;
|
|
55
58
|
readonly description: string;
|
|
56
59
|
readonly parameters: z.ZodObject<{
|
|
57
|
-
action: z.
|
|
60
|
+
action: z.ZodEnum<{
|
|
61
|
+
apply: "apply";
|
|
62
|
+
discard: "discard";
|
|
63
|
+
}>;
|
|
58
64
|
reason: z.ZodString;
|
|
59
65
|
extra: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
60
66
|
}, z.core.$strip>;
|
|
@@ -47,7 +47,6 @@ See [docs/custom-tools.md](../../docs/custom-tools.md) for full documentation.
|
|
|
47
47
|
**Factory pattern:**
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
import { StringEnum } from "@oh-my-pi/pi-ai";
|
|
51
50
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
52
51
|
import type { CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
|
|
53
52
|
|
|
@@ -56,7 +55,7 @@ const factory: CustomToolFactory = (pi) => ({
|
|
|
56
55
|
label: "My Tool",
|
|
57
56
|
description: "Tool description for LLM",
|
|
58
57
|
parameters: pi.zod.object({
|
|
59
|
-
action:
|
|
58
|
+
action: pi.zod.enum(["list", "add"]),
|
|
60
59
|
}),
|
|
61
60
|
|
|
62
61
|
// Called on session start/switch/branch/clear
|
|
@@ -76,9 +75,6 @@ const factory: CustomToolFactory = (pi) => ({
|
|
|
76
75
|
|
|
77
76
|
export default factory;
|
|
78
77
|
```
|
|
79
|
-
|
|
80
|
-
**Legacy:** `parameters: pi.typebox.Type.Object({ ... })` still works; the injected `typebox` is a small Zod-backed shim, and schemas flow through the same Zod pipeline as `pi.zod` schemas.
|
|
81
|
-
|
|
82
78
|
**Custom rendering:**
|
|
83
79
|
|
|
84
80
|
```typescript
|
|
@@ -97,17 +93,12 @@ renderResult(result, { expanded, isPartial }, theme) {
|
|
|
97
93
|
},
|
|
98
94
|
```
|
|
99
95
|
|
|
100
|
-
**Use `
|
|
96
|
+
**Use `z.enum` for discriminated string tool args:**
|
|
101
97
|
|
|
102
98
|
```typescript
|
|
103
|
-
import { StringEnum } from "@oh-my-pi/pi-ai";
|
|
104
|
-
|
|
105
99
|
const { z } = pi.zod;
|
|
106
100
|
|
|
107
|
-
// Good — Google-safe enum wiring
|
|
108
101
|
parameters: z.object({
|
|
109
|
-
action:
|
|
102
|
+
action: z.enum(["list", "add"]),
|
|
110
103
|
});
|
|
111
|
-
|
|
112
|
-
// Avoid raw union-of-literals patterns that don't degrade well for strict JSON Schema providers
|
|
113
104
|
```
|
|
@@ -108,29 +108,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
```
|
|
111
|
-
|
|
112
|
-
**Legacy TypeBox-style schemas** (`pi.typebox`) remain available for older extensions and are backed by a tiny Zod-shim — prefer `pi.zod` directly for new code.
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
const { Type } = pi.typebox;
|
|
116
|
-
parameters: Type.Object({ name: Type.String() });
|
|
117
|
-
```
|
|
118
|
-
|
|
119
111
|
## Key Patterns
|
|
120
112
|
|
|
121
|
-
**Use `
|
|
113
|
+
**Use `z.enum` for discriminated string tool args:**
|
|
122
114
|
|
|
123
115
|
```typescript
|
|
124
|
-
import { StringEnum } from "@oh-my-pi/pi-ai";
|
|
125
|
-
|
|
126
116
|
const { z } = pi.zod;
|
|
127
117
|
|
|
128
|
-
// Good — Google-safe enum wiring
|
|
129
118
|
parameters: z.object({
|
|
130
|
-
action:
|
|
119
|
+
action: z.enum(["list", "add"]),
|
|
131
120
|
});
|
|
132
|
-
|
|
133
|
-
// Avoid raw union-of-literals patterns that don't degrade well for strict JSON Schema providers
|
|
134
121
|
```
|
|
135
122
|
|
|
136
123
|
**State persistence via details:**
|
|
@@ -10,9 +10,6 @@ import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
|
|
|
10
10
|
export default function (pi: ExtensionAPI) {
|
|
11
11
|
const { z } = pi.zod;
|
|
12
12
|
|
|
13
|
-
// Access shared schema helpers from package exports (e.g. StringEnum for Google-safe enums)
|
|
14
|
-
const { StringEnum } = pi.pi;
|
|
15
|
-
|
|
16
13
|
// Access the logger for debugging
|
|
17
14
|
pi.logger.debug("API demo extension loaded");
|
|
18
15
|
|
|
@@ -22,10 +19,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
22
19
|
description: "Demonstrates ExtensionAPI capabilities: logger, zod, and pi module access",
|
|
23
20
|
parameters: z.object({
|
|
24
21
|
message: z.string().describe("Test message"),
|
|
25
|
-
logLevel:
|
|
26
|
-
description: "Log level to use",
|
|
27
|
-
default: "debug",
|
|
28
|
-
}),
|
|
22
|
+
logLevel: z.enum(["error", "warn", "debug"]).default("debug").describe("Log level to use"),
|
|
29
23
|
}),
|
|
30
24
|
|
|
31
25
|
async execute(_toolCallId, params, _onUpdate, ctx, _signal) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.1.
|
|
4
|
+
"version": "15.1.4",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.21.0",
|
|
48
48
|
"@babel/parser": "^7.29.3",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/omp-stats": "15.1.
|
|
51
|
-
"@oh-my-pi/pi-agent-core": "15.1.
|
|
52
|
-
"@oh-my-pi/pi-ai": "15.1.
|
|
53
|
-
"@oh-my-pi/pi-natives": "15.1.
|
|
54
|
-
"@oh-my-pi/pi-tui": "15.1.
|
|
55
|
-
"@oh-my-pi/pi-utils": "15.1.
|
|
50
|
+
"@oh-my-pi/omp-stats": "15.1.4",
|
|
51
|
+
"@oh-my-pi/pi-agent-core": "15.1.4",
|
|
52
|
+
"@oh-my-pi/pi-ai": "15.1.4",
|
|
53
|
+
"@oh-my-pi/pi-natives": "15.1.4",
|
|
54
|
+
"@oh-my-pi/pi-tui": "15.1.4",
|
|
55
|
+
"@oh-my-pi/pi-utils": "15.1.4",
|
|
56
56
|
"@puppeteer/browsers": "^2.13.0",
|
|
57
57
|
"@types/turndown": "5.0.6",
|
|
58
58
|
"@xterm/headless": "^6.0.0",
|