@raindrop-ai/wizard 0.0.3 → 0.0.5
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.
|
@@ -234,25 +234,26 @@ If you need full manual control over attachments, set `autoAttachment: false` in
|
|
|
234
234
|
`context` in `wrap()` is optional and useful for defaults. If both are
|
|
235
235
|
present, call-time `eventMetadata()` wins.
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
await generateText({
|
|
248
|
-
model,
|
|
249
|
-
prompt,
|
|
250
|
-
experimental_telemetry: {
|
|
251
|
-
isEnabled: true,
|
|
252
|
-
metadata: eventMetadata({ userId: actualUserId }),
|
|
237
|
+
```typescript
|
|
238
|
+
const { generateText } = raindrop.wrap(ai, {
|
|
239
|
+
context: {
|
|
240
|
+
userId, // Fallback defaults
|
|
241
|
+
properties: {
|
|
242
|
+
wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
|
|
253
243
|
},
|
|
254
|
-
}
|
|
255
|
-
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
await generateText({
|
|
248
|
+
model,
|
|
249
|
+
prompt,
|
|
250
|
+
experimental_telemetry: {
|
|
251
|
+
isEnabled: true,
|
|
252
|
+
metadata: eventMetadata({ userId: actualUserId }),
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
256
257
|
</Info>
|
|
257
258
|
|
|
258
259
|
---
|
|
@@ -431,14 +432,32 @@ const person = await result.object;
|
|
|
431
432
|
## ToolLoopAgent
|
|
432
433
|
|
|
433
434
|
<Info>Requires AI SDK v6 or later.</Info>
|
|
435
|
+
ToolLoopAgent is wrapped automatically. Both `generate()` and `stream()` trace tool
|
|
436
|
+
calls with their arguments and results. Pass per-call context via the top-level `metadata`
|
|
437
|
+
parameter.
|
|
438
|
+
|
|
439
|
+
### Typescript
|
|
440
|
+
|
|
441
|
+
`raindrop.wrap(ai)` changes the `ToolLoopAgent` method signatures to accept
|
|
442
|
+
top-level `metadata`, so typing against `ai.ToolLoopAgent` can cause TypeScript
|
|
443
|
+
errors. If you define your own agent type, wrap the AI SDK type with
|
|
444
|
+
`AgentWithMetadata` so `metadata` is still accepted on `generate()` and
|
|
445
|
+
`stream()`:
|
|
434
446
|
|
|
435
|
-
|
|
436
|
-
|
|
447
|
+
```typescript
|
|
448
|
+
import * as ai from 'ai';
|
|
449
|
+
import type { ToolSet } from 'ai';
|
|
450
|
+
import type { AgentWithMetadata } from '@raindrop-ai/ai-sdk';
|
|
451
|
+
|
|
452
|
+
export type YourToolLoopAgent = AgentWithMetadata<
|
|
453
|
+
ai.ToolLoopAgent<unknown, ToolSet, any>
|
|
454
|
+
>;
|
|
455
|
+
```
|
|
437
456
|
|
|
438
457
|
### generate
|
|
439
458
|
|
|
440
459
|
```typescript
|
|
441
|
-
import
|
|
460
|
+
import * as ai from 'ai';
|
|
442
461
|
import { openai } from '@ai-sdk/openai';
|
|
443
462
|
import { z } from 'zod';
|
|
444
463
|
import { createRaindropAISDK, eventMetadata } from '@raindrop-ai/ai-sdk';
|
|
@@ -447,15 +466,9 @@ const raindrop = createRaindropAISDK({
|
|
|
447
466
|
writeKey: process.env.RAINDROP_WRITE_KEY!,
|
|
448
467
|
});
|
|
449
468
|
|
|
450
|
-
const
|
|
451
|
-
context: {
|
|
452
|
-
properties: {
|
|
453
|
-
wizardSession: '__WIZARD_SESSION_UUID__', // REQUIRED
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
});
|
|
469
|
+
const wrapped = raindrop.wrap(ai);
|
|
457
470
|
|
|
458
|
-
const weatherTool = tool({
|
|
471
|
+
const weatherTool = ai.tool({
|
|
459
472
|
description: 'Get current weather',
|
|
460
473
|
parameters: z.object({ city: z.string() }),
|
|
461
474
|
execute: async ({ city }) => {
|
|
@@ -470,14 +483,11 @@ const agent = new ToolLoopAgent({
|
|
|
470
483
|
});
|
|
471
484
|
|
|
472
485
|
const result = await agent.generate({
|
|
473
|
-
prompt
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
eventName,
|
|
479
|
-
}),
|
|
480
|
-
},
|
|
486
|
+
prompt,
|
|
487
|
+
metadata: eventMetadata({
|
|
488
|
+
userId,
|
|
489
|
+
eventName,
|
|
490
|
+
}),
|
|
481
491
|
});
|
|
482
492
|
```
|
|
483
493
|
|
|
@@ -487,14 +497,11 @@ const result = await agent.generate({
|
|
|
487
497
|
import { eventMetadata } from '@raindrop-ai/ai-sdk';
|
|
488
498
|
|
|
489
499
|
const result = await agent.stream({
|
|
490
|
-
prompt
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
eventName,
|
|
496
|
-
}),
|
|
497
|
-
},
|
|
500
|
+
prompt,
|
|
501
|
+
metadata: eventMetadata({
|
|
502
|
+
userId,
|
|
503
|
+
eventName,
|
|
504
|
+
}),
|
|
498
505
|
});
|
|
499
506
|
|
|
500
507
|
for await (const chunk of result.textStream) {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
|
+
import { existsSync, writeFileSync } from 'fs';
|
|
8
|
+
import os from 'os';
|
|
7
9
|
import path from 'path';
|
|
8
10
|
import { debug, initLogFile, LOG_FILE_PATH, logToFile, } from '../utils/debug.js';
|
|
9
11
|
import ui from '../utils/ui.js';
|
|
@@ -21,6 +23,18 @@ function getClaudeCodeExecutablePath() {
|
|
|
21
23
|
const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');
|
|
22
24
|
return path.join(path.dirname(sdkPackagePath), 'cli.js');
|
|
23
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Ensure Claude CLI has a config file to read during startup.
|
|
28
|
+
* Some SDK/CLI versions error if ~/.claude.json is missing.
|
|
29
|
+
*/
|
|
30
|
+
function ensureClaudeConfigFileExists() {
|
|
31
|
+
const claudeConfigPath = path.join(os.homedir(), '.claude.json');
|
|
32
|
+
if (existsSync(claudeConfigPath)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
writeFileSync(claudeConfigPath, '{}\n', { encoding: 'utf-8' });
|
|
36
|
+
logToFile('Created missing Claude config file:', claudeConfigPath);
|
|
37
|
+
}
|
|
24
38
|
/**
|
|
25
39
|
* Async queue for user messages.
|
|
26
40
|
* Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.
|
|
@@ -85,6 +99,7 @@ export function initializeAgent(config, options) {
|
|
|
85
99
|
logToFile('Agent initialization starting');
|
|
86
100
|
logToFile('Install directory:', options.installDir);
|
|
87
101
|
try {
|
|
102
|
+
ensureClaudeConfigFileExists();
|
|
88
103
|
process.env.MAX_THINKING_TOKENS = '10000';
|
|
89
104
|
process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';
|
|
90
105
|
// Set default subagent model to Sonnet
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport { query, type SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport { createRequire } from 'module';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Sonnet\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'sonnet',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n successMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n successMessage = 'Raindrop integration complete',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const collectedText: string[] = [];\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n ui.setAgentState({ isRunning: true });\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n ui.setAgentState({ isRunning: false });\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n\n queryObject = query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: '{WIZARD_SYSTEM_PROMPT}',\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n }) as QueryObject;\n\n // Update agent state\n ui.setAgentState({\n isRunning: true,\n queryHandle: handle,\n });\n\n try {\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n ui.setAgentState({ sessionId });\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n }\n\n processSDKMessage(\n message,\n options,\n collectedText,\n pendingToolCalls,\n isInterruptingRef.value,\n { updateSpinner, baseSpinnerMessage: spinnerMessage },\n );\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n ui.setAgentState({ isRunning: false });\n\n if (completed) {\n spinner.stop(successMessage);\n } else if (isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-interface.js","sourceRoot":"","sources":["../../../src/lib/agent-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared agent interface for wizards\n * Uses Claude Agent SDK directly with streaming input support\n */\n\nimport { query, type SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';\nimport { createRequire } from 'module';\nimport { existsSync, writeFileSync } from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport type { AgentQueryHandle } from '../ui/types.js';\nimport {\n debug,\n initLogFile,\n LOG_FILE_PATH,\n logToFile,\n} from '../utils/debug.js';\nimport type { WizardOptions } from '../utils/types.js';\nimport ui from '../utils/ui.js';\nimport {\n createAgentQueryHandle,\n createCanUseToolHandler,\n createPreToolUseHook,\n type PendingToolCall,\n type SessionInfo,\n} from './handlers.js';\nimport { createMcpServer } from './mcp.js';\nimport { processSDKMessage } from './sdk-messages.js';\n\n// Create a require function for ESM compatibility\nconst require = createRequire(import.meta.url);\n\n/**\n * Get the path to the bundled Claude Code CLI from the SDK package.\n * This ensures we use the SDK's bundled version rather than the user's installed Claude Code.\n */\nfunction getClaudeCodeExecutablePath(): string {\n // require.resolve finds the package's main entry, then we get cli.js from same dir\n const sdkPackagePath = require.resolve('@anthropic-ai/claude-agent-sdk');\n return path.join(path.dirname(sdkPackagePath), 'cli.js');\n}\n\n/**\n * Ensure Claude CLI has a config file to read during startup.\n * Some SDK/CLI versions error if ~/.claude.json is missing.\n */\nfunction ensureClaudeConfigFileExists(): void {\n const claudeConfigPath = path.join(os.homedir(), '.claude.json');\n if (existsSync(claudeConfigPath)) {\n return;\n }\n\n writeFileSync(claudeConfigPath, '{}\\n', { encoding: 'utf-8' });\n logToFile('Created missing Claude config file:', claudeConfigPath);\n}\n\n// Re-export AgentQueryHandle for external use\nexport type { AgentQueryHandle };\n\nexport type AgentConfig = {\n workingDirectory: string;\n};\n\n/**\n * Result from runAgentLoop including session ID and query handle\n */\nexport interface AgentRunResult {\n sessionId?: string;\n handle: AgentQueryHandle;\n completed: boolean;\n}\n\n/**\n * Internal configuration object returned by initializeAgent\n */\nexport type AgentRunConfig = {\n workingDirectory: string;\n model: string;\n};\n\ntype QueuedUserMessage = {\n type: 'user';\n message: {\n role: 'user';\n content: string;\n };\n};\n\ntype QueryMessage = {\n type?: string;\n session_id?: string;\n [key: string]: unknown;\n};\n\ntype QueryObject = AsyncIterable<QueryMessage> & {\n interrupt?: () => Promise<void>;\n};\n\n/**\n * Async queue for user messages.\n * Messages are pushed by UI callbacks and consumed by the SDK as an async iterable.\n */\nclass UserMessageQueue implements AsyncIterable<QueuedUserMessage> {\n private messages: QueuedUserMessage[] = [];\n\n private waitingResolver:\n | ((message: QueuedUserMessage | null) => void)\n | null = null;\n\n private closed = false;\n\n push(content: string): void {\n if (this.closed) {\n return;\n }\n\n const message: QueuedUserMessage = {\n type: 'user',\n message: {\n role: 'user',\n content,\n },\n };\n\n if (this.waitingResolver) {\n this.waitingResolver(message);\n this.waitingResolver = null;\n return;\n }\n\n this.messages.push(message);\n }\n\n hasPending(): boolean {\n return this.messages.length > 0;\n }\n\n close(): void {\n this.closed = true;\n if (this.waitingResolver) {\n this.waitingResolver(null);\n this.waitingResolver = null;\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterableIterator<QueuedUserMessage> {\n while (!this.closed) {\n if (this.messages.length > 0) {\n const nextMessage = this.messages.shift();\n if (nextMessage) {\n yield nextMessage;\n }\n continue;\n }\n\n const nextMessage = await new Promise<QueuedUserMessage | null>(\n (resolve) => {\n this.waitingResolver = resolve;\n },\n );\n\n if (!nextMessage) {\n return;\n }\n\n yield nextMessage;\n }\n }\n}\n\n/**\n * Initialize agent configuration for the Claude agent\n */\nexport function initializeAgent(\n config: AgentConfig,\n options: WizardOptions,\n): AgentRunConfig {\n // Initialize log file for this run\n initLogFile();\n logToFile('Agent initialization starting');\n logToFile('Install directory:', options.installDir);\n\n try {\n ensureClaudeConfigFileExists();\n process.env.MAX_THINKING_TOKENS = '10000';\n process.env.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 'true';\n // Set default subagent model to Sonnet\n process.env.CLAUDE_CODE_SUBAGENT_MODEL = 'claude-sonnet-4-5-20250929';\n\n const agentRunConfig: AgentRunConfig = {\n workingDirectory: config.workingDirectory,\n model: 'sonnet',\n };\n\n logToFile('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n\n if (options.debug) {\n debug('Agent config:', {\n workingDirectory: agentRunConfig.workingDirectory,\n });\n }\n\n ui.addItem({\n type: 'step',\n text: `I'll keep verbose logs for this session at: ${LOG_FILE_PATH}`,\n });\n return agentRunConfig;\n } catch (error) {\n ui.addItem({\n type: 'error',\n text: `Failed to initialize agent: ${(error as Error).message}`,\n });\n logToFile('Agent initialization error:', error);\n debug('Agent initialization error:', error);\n throw error;\n }\n}\n\n/**\n * Configuration for runAgentLoop\n */\nexport interface RunAgentConfig {\n spinnerMessage?: string;\n successMessage?: string;\n accessToken: string;\n orgId: string;\n onCompleteIntegration?: () => Promise<boolean | string>;\n}\n\n/**\n * Execute an agent with the provided prompt and options.\n * Supports streaming input for user interruption and follow-up messages.\n * Uses a single long-lived SDK query fed by an async message queue.\n *\n * @returns Session ID and query handle for controlling the agent\n */\nexport async function runAgentLoop(\n agentConfig: AgentRunConfig,\n prompt: string,\n options: WizardOptions,\n config: RunAgentConfig,\n): Promise<AgentRunResult> {\n const {\n spinnerMessage = 'Raindrop wizard is working...',\n successMessage = 'Raindrop integration complete',\n accessToken,\n orgId,\n onCompleteIntegration,\n } = config;\n\n // Add header to indicate start of interactive agent phase\n ui.addItem({ type: 'phase', text: '─── Agent ───' });\n\n const cliPath = getClaudeCodeExecutablePath();\n logToFile('Starting agent run');\n logToFile('Claude Code executable:', cliPath);\n\n const startTime = Date.now();\n const inputQueue = new UserMessageQueue();\n inputQueue.push(prompt);\n\n const approvedFilesCache = new Set<string>();\n const collectedText: string[] = [];\n const pendingToolCalls = new Map<string, PendingToolCall>();\n\n const hasCompletedWorkRef = { value: false };\n const isInterruptingRef = { value: false };\n const waitingForUserInputRef = { value: false };\n const exitHintShownRef = { value: false };\n\n let sessionId: string | undefined;\n let queryObject: QueryObject | null = null;\n let isSpinnerRunning = false;\n let completed = false;\n let shouldEndSession = false;\n\n const spinner = ui.spinner();\n\n // Track current spinner base message and when it last changed.\n let currentSpinnerMsg = spinnerMessage;\n let lastActivityTime = Date.now();\n\n const updateSpinner = (msg: string) => {\n if (!isSpinnerRunning) return;\n currentSpinnerMsg = msg;\n lastActivityTime = Date.now();\n spinner.message(msg);\n };\n\n // Every second, if the agent has been silent for >= 10s, append a counting thinking indicator.\n // Pure JS interval — Ink only re-renders when the string actually changes.\n const thinkingTimer = setInterval(() => {\n if (!isSpinnerRunning) return;\n const idleS = Math.floor((Date.now() - lastActivityTime) / 1000);\n if (idleS >= 20) {\n const mins = Math.floor(idleS / 60);\n const secs = idleS % 60;\n const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;\n spinner.message(`${currentSpinnerMsg} (thinking · ${timeStr})`);\n }\n }, 1000);\n\n const setAgentRunning = (isRunning: boolean) => {\n if (isRunning) {\n if (!isSpinnerRunning) {\n spinner.start(spinnerMessage);\n isSpinnerRunning = true;\n }\n ui.setAgentState({ isRunning: true });\n return;\n }\n\n if (isSpinnerRunning) {\n spinner.stop();\n isSpinnerRunning = false;\n }\n ui.setAgentState({ isRunning: false });\n };\n\n // Create MCP server with CompleteIntegration tool\n const toolsMcpServer = createMcpServer(hasCompletedWorkRef, {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n installDir: agentConfig.workingDirectory,\n });\n\n // Session info for notifications\n const sessionInfo: SessionInfo = {\n sessionId: options.sessionId,\n accessToken,\n orgId,\n };\n\n const handle = createAgentQueryHandle({\n isInterruptingRef,\n waitingForUserInputRef,\n pendingToolCalls,\n getQueryObject: () => queryObject,\n sendMessage: (message: string) => {\n inputQueue.push(message);\n },\n });\n\n const startPersistentInput = (placeholder?: string) => {\n ui.startPersistentInput({\n onSubmit: handlePersistentSubmit,\n onInterrupt: handlePersistentInterrupt,\n onCtrlC: handlePersistentCtrlC,\n placeholder,\n });\n };\n\n // Define callbacks for persistent input\n const handlePersistentSubmit = (message: string) => {\n const trimmedMessage = message.trim();\n if (!trimmedMessage) {\n return;\n }\n\n exitHintShownRef.value = false;\n\n ui.addItem({\n type: 'user-message',\n text: trimmedMessage,\n });\n\n handle.sendMessage(trimmedMessage);\n\n if (waitingForUserInputRef.value) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n return;\n }\n\n if (!isInterruptingRef.value) {\n logToFile(\n 'User submitted message while agent is running - interrupting current turn',\n );\n void handle.interrupt(true);\n }\n };\n\n const handlePersistentInterrupt = () => {\n logToFile('User requested interrupt (Esc)');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n const handlePersistentCtrlC = () => {\n logToFile('User pressed Ctrl+C');\n\n // If already interrupted and exit hint was shown, exit immediately\n if (\n (isInterruptingRef.value || waitingForUserInputRef.value) &&\n exitHintShownRef.value\n ) {\n logToFile('Second Ctrl+C - exiting');\n ui.stopPersistentInput();\n ui.exit();\n // Small delay to allow UI to clean up before exit\n setTimeout(() => process.exit(130), 100);\n return;\n }\n\n // If already interrupted but hint not shown yet, show hint and clear input\n if (isInterruptingRef.value || waitingForUserInputRef.value) {\n logToFile('First Ctrl+C while interrupted - showing exit hint');\n exitHintShownRef.value = true;\n ui.stopPersistentInput();\n startPersistentInput('Press Ctrl+C again to exit');\n return;\n }\n\n // Not interrupted yet - treat as normal interrupt\n logToFile('First Ctrl+C - triggering interrupt');\n setAgentRunning(false);\n void handle.interrupt();\n };\n\n startPersistentInput();\n setAgentRunning(true);\n\n queryObject = query({\n prompt: inputQueue as unknown as AsyncIterable<SDKUserMessage>,\n options: {\n model: agentConfig.model,\n cwd: agentConfig.workingDirectory,\n permissionMode: 'default',\n mcpServers: {\n 'raindrop-wizard': toolsMcpServer,\n },\n systemPrompt: '{WIZARD_SYSTEM_PROMPT}',\n env: { ...process.env },\n canUseTool: createCanUseToolHandler(approvedFilesCache),\n hooks: {\n PreToolUse: [{ hooks: [createPreToolUseHook(sessionInfo)] }],\n },\n stderr: (data: string) => {\n logToFile('CLI stderr:', data);\n if (options.debug) {\n debug('CLI stderr:', data);\n }\n },\n },\n }) as QueryObject;\n\n // Update agent state\n ui.setAgentState({\n isRunning: true,\n queryHandle: handle,\n });\n\n try {\n for await (const message of queryObject) {\n // Capture session_id from any message\n if (message.session_id && !sessionId) {\n sessionId = message.session_id;\n ui.setAgentState({ sessionId });\n }\n\n // If we were waiting for user input but got a new message,\n // the queued message has started processing.\n if (\n waitingForUserInputRef.value &&\n !isInterruptingRef.value &&\n message.type !== 'result'\n ) {\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n setAgentRunning(true);\n }\n\n processSDKMessage(\n message,\n options,\n collectedText,\n pendingToolCalls,\n isInterruptingRef.value,\n { updateSpinner, baseSpinnerMessage: spinnerMessage },\n );\n\n if (message.type !== 'result') {\n continue;\n }\n\n if (hasCompletedWorkRef.value) {\n setAgentRunning(false);\n ui.stopPersistentInput();\n\n const completionDecision = onCompleteIntegration\n ? await onCompleteIntegration()\n : true;\n\n if (typeof completionDecision === 'string') {\n const feedbackPrompt = completionDecision.trim();\n if (!feedbackPrompt) {\n logToFile('Received empty feedback prompt - ending session');\n completed = false;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n logToFile('Received testing feedback - queueing feedback prompt');\n hasCompletedWorkRef.value = false;\n waitingForUserInputRef.value = false;\n isInterruptingRef.value = false;\n handle.sendMessage(feedbackPrompt);\n startPersistentInput();\n setAgentRunning(true);\n continue;\n }\n\n completed = completionDecision;\n shouldEndSession = true;\n inputQueue.close();\n break;\n }\n\n // Turn ended without completion. If there are no queued messages,\n // we are waiting for the user to submit the next one.\n isInterruptingRef.value = false;\n\n if (!inputQueue.hasPending()) {\n waitingForUserInputRef.value = true;\n setAgentRunning(false);\n } else {\n waitingForUserInputRef.value = false;\n setAgentRunning(true);\n }\n }\n } finally {\n inputQueue.close();\n clearInterval(thinkingTimer);\n }\n\n const durationMs = Date.now() - startTime;\n logToFile(`Agent session completed in ${Math.round(durationMs / 1000)}s`);\n logToFile('Session ID:', sessionId);\n logToFile('Completion status:', hasCompletedWorkRef.value);\n\n if (!shouldEndSession && hasCompletedWorkRef.value) {\n // Fallback: if stream ended after completion, mark as completed.\n completed = true;\n }\n\n ui.stopPersistentInput();\n ui.setAgentState({ isRunning: false });\n\n if (completed) {\n spinner.stop(successMessage);\n } else if (isSpinnerRunning) {\n spinner.stop();\n }\n\n return { sessionId, handle, completed };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/wizard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://github.com/raindrop/wizard",
|
|
6
6
|
"repository": "https://github.com/raindrop/wizard",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"definition": "dist/index.d.ts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@anthropic-ai/claude-agent-sdk": "0.2.
|
|
37
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.50",
|
|
38
38
|
"@inkkit/ink-markdown": "^1.0.0",
|
|
39
39
|
"chalk": "^2.4.1",
|
|
40
40
|
"clipboardy": "^4.0.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"typescript": "^5.0.4"
|
|
82
82
|
},
|
|
83
83
|
"engines": {
|
|
84
|
-
"node": ">=
|
|
84
|
+
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
|
85
85
|
},
|
|
86
86
|
"packageManager": "yarn@1.22.22",
|
|
87
87
|
"scripts": {
|