@witqq/agent-sdk 0.5.2 → 0.6.1

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/README.md CHANGED
@@ -367,6 +367,18 @@ const agent = service.createAgent({
367
367
 
368
368
  Uses `generateText()` for runs, `generateObject()` for structured output, `streamText()` for streaming. Supports `supervisor.onAskUser` via an injected `ask_user` tool.
369
369
 
370
+ Pass model-specific options via `providerOptions`:
371
+
372
+ ```typescript
373
+ const agent = service.createAgent({
374
+ model: "google/gemini-2.0-flash",
375
+ systemPrompt: "Think step by step.",
376
+ providerOptions: {
377
+ google: { thinkingConfig: { thinkingBudget: 1024 } },
378
+ },
379
+ });
380
+ ```
381
+
370
382
  ## Switching Backends
371
383
 
372
384
  All backends share the same `AgentConfig` and return the same `AgentResult`. To switch backends, change only the service creation:
@@ -492,17 +504,17 @@ interface CopilotAuthToken extends AuthToken {
492
504
 
493
505
  ## Interactive Demo
494
506
 
495
- A web-based interactive demo showcasing all backends with authentication is in `examples/auth-demo/`.
507
+ An interactive demo for testing multi-turn conversations across all backends is in `examples/auth-demo/`.
496
508
 
497
509
  ```bash
498
- # Run in Docker (web UI at http://localhost:3456)
499
- docker compose -f examples/auth-demo/docker-compose.yml up
500
-
501
- # Run locally (CLI mode)
510
+ # CLI mode
502
511
  npx tsx examples/auth-demo/index.ts
512
+
513
+ # Web UI via Docker (http://localhost:3456)
514
+ docker compose -f examples/auth-demo/docker-compose.yml up
503
515
  ```
504
516
 
505
- Features: provider selection, auth flows (Device Flow, OAuth+PKCE, API key), model selection, streaming chat with conversation history, token persistence across container restarts, and provider switching.
517
+ Features: backend selection, auth flows (Device Flow, OAuth+PKCE, API key), multi-turn chat with persistent sessions, 7 keyboard shortcuts for common test messages, 3 demo tools (search, calculator, format with approval), streaming event display with ANSI colors, per-turn statistics, and provider switching.
506
518
 
507
519
  ## License
508
520
 
@@ -327,6 +327,14 @@ function extractSchemaFromDef(schema) {
327
327
  }
328
328
 
329
329
  // src/backends/claude.ts
330
+ var MCP_SERVER_NAME = "agent-sdk-tools";
331
+ var MCP_TOOL_PREFIX = `mcp__${MCP_SERVER_NAME}__`;
332
+ function mcpToolName(toolName) {
333
+ return `${MCP_TOOL_PREFIX}${toolName}`;
334
+ }
335
+ function stripMcpPrefix(name) {
336
+ return name.startsWith(MCP_TOOL_PREFIX) ? name.slice(MCP_TOOL_PREFIX.length) : name;
337
+ }
330
338
  var sdkModule = null;
331
339
  async function loadSDK() {
332
340
  if (sdkModule) return sdkModule;
@@ -350,11 +358,13 @@ var ANTHROPIC_API_VERSION = "2023-06-01";
350
358
  var ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
351
359
  function buildMcpServer(sdk, tools, toolResultCapture) {
352
360
  if (tools.length === 0) return void 0;
353
- const mcpTools = tools.map(
354
- (tool) => sdk.tool(
361
+ const mcpTools = tools.map((tool) => {
362
+ const zodSchema = tool.parameters;
363
+ const inputSchema = zodSchema.shape ?? zodToJsonSchema(tool.parameters);
364
+ return sdk.tool(
355
365
  tool.name,
356
366
  tool.description ?? "",
357
- zodToJsonSchema(tool.parameters),
367
+ inputSchema,
358
368
  async (args) => {
359
369
  const result = await tool.execute(args);
360
370
  if (toolResultCapture) {
@@ -369,10 +379,10 @@ function buildMcpServer(sdk, tools, toolResultCapture) {
369
379
  ]
370
380
  };
371
381
  }
372
- )
373
- );
382
+ );
383
+ });
374
384
  return sdk.createSdkMcpServer({
375
- name: "agent-sdk-tools",
385
+ name: MCP_SERVER_NAME,
376
386
  version: "1.0.0",
377
387
  tools: mcpTools
378
388
  });
@@ -409,7 +419,8 @@ function buildCanUseTool(config) {
409
419
  const onPermission = config.supervisor?.onPermission;
410
420
  if (!onPermission) return void 0;
411
421
  const permissionStore = config.permissionStore;
412
- return async (toolName, input, options) => {
422
+ return async (rawToolName, input, options) => {
423
+ const toolName = stripMcpPrefix(rawToolName);
413
424
  if (permissionStore && await permissionStore.isApproved(toolName)) {
414
425
  return {
415
426
  behavior: "allow",
@@ -491,14 +502,10 @@ function mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker) {
491
502
  const betaMessage = msg.message;
492
503
  if (!betaMessage?.content) return null;
493
504
  const events = [];
494
- const textParts = betaMessage.content.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("");
495
- if (textParts) {
496
- events.push({ type: "text_delta", text: textParts });
497
- }
498
505
  for (const block of betaMessage.content) {
499
506
  if (block.type === "tool_use") {
500
507
  const toolCallId = String(block.id ?? "");
501
- const toolName = block.name ?? "unknown";
508
+ const toolName = stripMcpPrefix(block.name ?? "unknown");
502
509
  if (toolCallTracker) {
503
510
  toolCallTracker.trackStart(toolCallId, toolName);
504
511
  }
@@ -521,7 +528,7 @@ function mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker) {
521
528
  }
522
529
  case "tool_use_summary": {
523
530
  const summary = msg.summary;
524
- const toolName = msg.tool_name ?? "unknown";
531
+ const toolName = stripMcpPrefix(msg.tool_name ?? "unknown");
525
532
  const precedingIds = msg.preceding_tool_use_ids;
526
533
  let toolCallId = "";
527
534
  if (precedingIds && precedingIds.length > 0) {
@@ -530,15 +537,12 @@ function mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker) {
530
537
  } else if (toolCallTracker) {
531
538
  toolCallId = toolCallTracker.consumeToolCallId(toolName);
532
539
  }
533
- if (summary) {
534
- return {
535
- type: "tool_call_end",
536
- toolCallId,
537
- toolName,
538
- result: summary
539
- };
540
- }
541
- return null;
540
+ return {
541
+ type: "tool_call_end",
542
+ toolCallId,
543
+ toolName,
544
+ result: summary ?? null
545
+ };
542
546
  }
543
547
  case "stream_event": {
544
548
  const event = msg.event;
@@ -566,10 +570,7 @@ function mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker) {
566
570
  return null;
567
571
  }
568
572
  case "tool_progress": {
569
- const toolName = msg.tool_name;
570
- if (!toolName) return null;
571
- const toolCallId = toolCallTracker?.peekToolCallId(toolName) ?? "";
572
- return { type: "tool_call_start", toolCallId, toolName, args: {} };
573
+ return null;
573
574
  }
574
575
  case "result": {
575
576
  if (msg.subtype === "success") {
@@ -664,6 +665,9 @@ var ClaudeAgent = class extends BaseAgent {
664
665
  if (opts.canUseTool && !opts.permissionMode) {
665
666
  opts.permissionMode = "default";
666
667
  }
668
+ if (this.config.availableTools) {
669
+ opts.allowedTools = [...this.config.availableTools];
670
+ }
667
671
  return opts;
668
672
  }
669
673
  async buildMcpConfig(opts, toolResultCapture) {
@@ -672,8 +676,10 @@ var ClaudeAgent = class extends BaseAgent {
672
676
  const mcpServer = buildMcpServer(sdk, this.tools, toolResultCapture);
673
677
  if (mcpServer) {
674
678
  opts.mcpServers = {
675
- "agent-sdk-tools": mcpServer
679
+ [MCP_SERVER_NAME]: mcpServer
676
680
  };
681
+ const mcpToolNames = this.tools.map((t) => mcpToolName(t.name));
682
+ opts.allowedTools = [...opts.allowedTools ?? [], ...mcpToolNames];
677
683
  }
678
684
  return opts;
679
685
  }
@@ -698,7 +704,7 @@ var ClaudeAgent = class extends BaseAgent {
698
704
  if (betaMessage?.content) {
699
705
  for (const block of betaMessage.content) {
700
706
  if (block.type === "tool_use") {
701
- const toolName = block.name ?? "unknown";
707
+ const toolName = stripMcpPrefix(block.name ?? "unknown");
702
708
  toolCalls.push({
703
709
  toolName,
704
710
  args: block.input ?? {},
@@ -758,7 +764,8 @@ var ClaudeAgent = class extends BaseAgent {
758
764
  const isResuming = this.isPersistent && this._sessionId !== void 0;
759
765
  const prompt = isResuming ? extractLastUserPrompt(messages) : buildContextualPrompt(messages);
760
766
  let opts = this.buildQueryOptions(signal);
761
- opts = await this.buildMcpConfig(opts);
767
+ const toolResultCapture = /* @__PURE__ */ new Map();
768
+ opts = await this.buildMcpConfig(opts, toolResultCapture);
762
769
  const jsonSchema = zodToJsonSchema(schema.schema);
763
770
  opts.outputFormat = {
764
771
  type: "json_schema",
@@ -772,6 +779,30 @@ var ClaudeAgent = class extends BaseAgent {
772
779
  let usage;
773
780
  try {
774
781
  for await (const msg of q) {
782
+ if (msg.type === "assistant") {
783
+ const betaMessage = msg.message;
784
+ if (betaMessage?.content) {
785
+ for (const block of betaMessage.content) {
786
+ if (block.type === "tool_use") {
787
+ const toolName = stripMcpPrefix(block.name ?? "unknown");
788
+ toolCalls.push({
789
+ toolName,
790
+ args: block.input ?? {},
791
+ result: toolResultCapture.get(toolName) ?? null,
792
+ approved: true
793
+ });
794
+ }
795
+ }
796
+ }
797
+ }
798
+ if (msg.type === "tool_use_summary" || msg.type === "result") {
799
+ for (const tc of toolCalls) {
800
+ if (tc.result === null) {
801
+ const captured = toolResultCapture.get(tc.toolName);
802
+ if (captured !== void 0) tc.result = captured;
803
+ }
804
+ }
805
+ }
775
806
  if (msg.type === "result" && msg.subtype === "success") {
776
807
  const r = msg;
777
808
  output = r.result;
@@ -836,13 +867,10 @@ var ClaudeAgent = class extends BaseAgent {
836
867
  try {
837
868
  for await (const msg of q) {
838
869
  if (signal.aborted) throw new AbortError();
839
- const event = mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker);
840
- if (event) {
841
- if (Array.isArray(event)) {
842
- for (const e of event) yield e;
843
- } else {
844
- yield event;
845
- }
870
+ const events = mapSDKMessage(msg, thinkingBlockIndices, toolCallTracker);
871
+ if (events) {
872
+ const mapped = Array.isArray(events) ? events : [events];
873
+ for (const e of mapped) yield e;
846
874
  }
847
875
  if (msg.type === "result" && msg.subtype === "success") {
848
876
  const r = msg;