The Co-Founder beforeToolCall hook (introduced in 77f81a7) gated every
non-readonly pi tool call as a `dangerous_command` approval. Because
agents call `POST /api/companies/:id/messages`, `/agents` (hire), and
every other company mutation via bash→node/curl, the first bash call in
every Co-Founder run got parked on a 30-minute approval timeout. Users
observed it as "agents never talk to each other" and "every bash command
waits for approval"; both symptoms are the same bug.
The business-level approval flow (`hire_agent`, `document_review`,
`plan_review`, etc. in execution-policy.ts) already gates the events
users actually care about, at the HTTP route layer where the event
originates (routes-agents.ts:368 for hiring, document routes for
deliverables). Stacking a pi-level hook on top was duplicate gating with
the wrong taxonomy.
Removed:
- src/main/agent-runtime/approval-hook.ts (entire file, 137 LOC)
- `beforeToolCall` conditional in worker-runner.ts and the
corresponding RPC method in worker-types.ts and runtime-bridge.ts
- `approvalHook` field + `resolveApproval` callback + shutdown
`cancelAll` in runtime-bridge.ts / service-graph-pi-runtime.ts /
wire-api-server.ts
Unchanged:
- `dangerous_command` approval type itself (still used by automation
workflows and routes-misc.ts)
- CEO mode (already never attached the hook)
- All business-level approval types and their wiring
57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
/**
|
|
* Pi-mono runtime + credential service factory.
|
|
*
|
|
* Composes `CredentialStore`, `CredentialResolver`, `OAuthLoginService`, and
|
|
* `RuntimeBridge` for `service-graph.ts`. Extracted to keep `service-graph.ts`
|
|
* under the 400-line cap.
|
|
*/
|
|
|
|
import type { AppDatabase } from "./database";
|
|
import type { DesktopEvent } from "@shared/types";
|
|
import { CredentialResolver, CredentialStore, OAuthLoginService } from "./credentials";
|
|
import { RuntimeBridge } from "./agent-runtime";
|
|
|
|
export interface PiRuntimeServicesDeps {
|
|
db: AppDatabase;
|
|
emitEvent: (event: DesktopEvent) => void;
|
|
refreshConnectorHealth: (connectorId: string) => Promise<void>;
|
|
logger: {
|
|
info: (...args: unknown[]) => void;
|
|
warn: (...args: unknown[]) => void;
|
|
error: (...args: unknown[]) => void;
|
|
};
|
|
}
|
|
|
|
export interface PiRuntimeServices {
|
|
credentialStore: CredentialStore;
|
|
credentialResolver: CredentialResolver;
|
|
oauthLoginService: OAuthLoginService;
|
|
runtimeBridge: RuntimeBridge;
|
|
release: () => void;
|
|
}
|
|
|
|
export function createPiRuntimeServices(deps: PiRuntimeServicesDeps): PiRuntimeServices {
|
|
const credentialStore = new CredentialStore({ db: deps.db });
|
|
const credentialResolver = new CredentialResolver(credentialStore);
|
|
const oauthLoginService = new OAuthLoginService({
|
|
store: credentialStore,
|
|
emitEvent: deps.emitEvent,
|
|
refreshConnectorHealth: deps.refreshConnectorHealth,
|
|
logger: deps.logger,
|
|
});
|
|
const runtimeBridge = new RuntimeBridge({
|
|
db: deps.db,
|
|
emitEvent: deps.emitEvent,
|
|
logger: deps.logger,
|
|
credentialResolver,
|
|
});
|
|
|
|
return {
|
|
credentialStore,
|
|
credentialResolver,
|
|
oauthLoginService,
|
|
runtimeBridge,
|
|
release: () => {},
|
|
};
|
|
}
|