@yourgpt/llm-sdk 0.1.1 → 1.0.0

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/dist/index.d.mts CHANGED
@@ -5,7 +5,7 @@ export { createOpenAI, openai } from './providers/openai/index.mjs';
5
5
  export { anthropic, createAnthropic } from './providers/anthropic/index.mjs';
6
6
  export { createXAI, xai } from './providers/xai/index.mjs';
7
7
  export { createGoogle, google } from './providers/google/index.mjs';
8
- import { LLMConfig, ActionDefinition, ToolDefinition, AgentLoopConfig, KnowledgeBaseConfig, StreamEvent, DoneEventMessage, Message, AIProvider as AIProvider$1, ToolResponse } from '@yourgpt/copilot-sdk/core';
8
+ import { LLMConfig, ActionDefinition, ToolDefinition, AgentLoopConfig, KnowledgeBaseConfig, DoneEventMessage, StreamEvent, Message, AIProvider as AIProvider$1, ToolResponse } from '@yourgpt/copilot-sdk/core';
9
9
  export { ActionDefinition, AgentLoopConfig, LLMConfig, LLMProvider, Message, StreamEvent, ToolDefinition, ToolExecution, ToolLocation, ToolResponse, UnifiedToolCall, UnifiedToolResult } from '@yourgpt/copilot-sdk/core';
10
10
  import { A as AIProvider, P as ProviderCapabilities, d as ProviderFormatter } from './types-BBCZ3Fxy.mjs';
11
11
  export { c as AnthropicProviderConfig, e as AnthropicTool, g as AnthropicToolResult, f as AnthropicToolUse, a as AzureProviderConfig, B as BaseProviderConfig, l as GeminiFunctionCall, k as GeminiFunctionDeclaration, m as GeminiFunctionResponse, G as GoogleProviderConfig, O as OllamaProviderConfig, b as OpenAIProviderConfig, h as OpenAITool, i as OpenAIToolCall, j as OpenAIToolResult, X as XAIProviderConfig } from './types-BBCZ3Fxy.mjs';
@@ -366,6 +366,45 @@ interface RequestContext {
366
366
  body: ChatRequest;
367
367
  }
368
368
 
369
+ /**
370
+ * Result passed to onFinish callback after stream completes
371
+ */
372
+ interface HandleRequestResult {
373
+ /** All messages from this request (assistant messages + tool results) */
374
+ messages: DoneEventMessage[];
375
+ /** Thread ID if provided in request */
376
+ threadId?: string;
377
+ /** Token usage information */
378
+ usage?: {
379
+ promptTokens: number;
380
+ completionTokens: number;
381
+ totalTokens: number;
382
+ };
383
+ }
384
+ /**
385
+ * Options for handleRequest method
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * runtime.handleRequest(request, {
390
+ * onFinish: async ({ messages, threadId }) => {
391
+ * await db.thread.upsert({
392
+ * where: { id: threadId },
393
+ * update: { messages, updatedAt: new Date() },
394
+ * create: { id: threadId, messages },
395
+ * });
396
+ * },
397
+ * });
398
+ * ```
399
+ */
400
+ interface HandleRequestOptions {
401
+ /**
402
+ * Called after the stream completes successfully.
403
+ * Use this for server-side persistence of messages.
404
+ */
405
+ onFinish?: (result: HandleRequestResult) => Promise<void> | void;
406
+ }
407
+
369
408
  /**
370
409
  * Copilot SDK Runtime
371
410
  *
@@ -387,8 +426,32 @@ declare class Runtime {
387
426
  processChat(request: ChatRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
388
427
  /**
389
428
  * Handle HTTP request (for use with any framework)
429
+ *
430
+ * @param request - The HTTP request
431
+ * @param options - Optional configuration including onFinish callback for persistence
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * // Basic usage
436
+ * return runtime.handleRequest(request);
437
+ *
438
+ * // With server-side persistence
439
+ * return runtime.handleRequest(request, {
440
+ * onFinish: async ({ messages, threadId }) => {
441
+ * await db.thread.upsert({
442
+ * where: { id: threadId },
443
+ * update: { messages, updatedAt: new Date() },
444
+ * create: { id: threadId, messages },
445
+ * });
446
+ * },
447
+ * });
448
+ * ```
449
+ */
450
+ handleRequest(request: Request, options?: HandleRequestOptions): Promise<Response>;
451
+ /**
452
+ * Wrap a generator to intercept the done event and call onFinish
390
453
  */
391
- handleRequest(request: Request): Promise<Response>;
454
+ private wrapGeneratorWithOnFinish;
392
455
  /**
393
456
  * Handle non-streaming request - returns JSON instead of SSE
394
457
  */
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { createOpenAI, openai } from './providers/openai/index.js';
5
5
  export { anthropic, createAnthropic } from './providers/anthropic/index.js';
6
6
  export { createXAI, xai } from './providers/xai/index.js';
7
7
  export { createGoogle, google } from './providers/google/index.js';
8
- import { LLMConfig, ActionDefinition, ToolDefinition, AgentLoopConfig, KnowledgeBaseConfig, StreamEvent, DoneEventMessage, Message, AIProvider as AIProvider$1, ToolResponse } from '@yourgpt/copilot-sdk/core';
8
+ import { LLMConfig, ActionDefinition, ToolDefinition, AgentLoopConfig, KnowledgeBaseConfig, DoneEventMessage, StreamEvent, Message, AIProvider as AIProvider$1, ToolResponse } from '@yourgpt/copilot-sdk/core';
9
9
  export { ActionDefinition, AgentLoopConfig, LLMConfig, LLMProvider, Message, StreamEvent, ToolDefinition, ToolExecution, ToolLocation, ToolResponse, UnifiedToolCall, UnifiedToolResult } from '@yourgpt/copilot-sdk/core';
10
10
  import { A as AIProvider, P as ProviderCapabilities, d as ProviderFormatter } from './types-DcoCaVVC.js';
11
11
  export { c as AnthropicProviderConfig, e as AnthropicTool, g as AnthropicToolResult, f as AnthropicToolUse, a as AzureProviderConfig, B as BaseProviderConfig, l as GeminiFunctionCall, k as GeminiFunctionDeclaration, m as GeminiFunctionResponse, G as GoogleProviderConfig, O as OllamaProviderConfig, b as OpenAIProviderConfig, h as OpenAITool, i as OpenAIToolCall, j as OpenAIToolResult, X as XAIProviderConfig } from './types-DcoCaVVC.js';
@@ -366,6 +366,45 @@ interface RequestContext {
366
366
  body: ChatRequest;
367
367
  }
368
368
 
369
+ /**
370
+ * Result passed to onFinish callback after stream completes
371
+ */
372
+ interface HandleRequestResult {
373
+ /** All messages from this request (assistant messages + tool results) */
374
+ messages: DoneEventMessage[];
375
+ /** Thread ID if provided in request */
376
+ threadId?: string;
377
+ /** Token usage information */
378
+ usage?: {
379
+ promptTokens: number;
380
+ completionTokens: number;
381
+ totalTokens: number;
382
+ };
383
+ }
384
+ /**
385
+ * Options for handleRequest method
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * runtime.handleRequest(request, {
390
+ * onFinish: async ({ messages, threadId }) => {
391
+ * await db.thread.upsert({
392
+ * where: { id: threadId },
393
+ * update: { messages, updatedAt: new Date() },
394
+ * create: { id: threadId, messages },
395
+ * });
396
+ * },
397
+ * });
398
+ * ```
399
+ */
400
+ interface HandleRequestOptions {
401
+ /**
402
+ * Called after the stream completes successfully.
403
+ * Use this for server-side persistence of messages.
404
+ */
405
+ onFinish?: (result: HandleRequestResult) => Promise<void> | void;
406
+ }
407
+
369
408
  /**
370
409
  * Copilot SDK Runtime
371
410
  *
@@ -387,8 +426,32 @@ declare class Runtime {
387
426
  processChat(request: ChatRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
388
427
  /**
389
428
  * Handle HTTP request (for use with any framework)
429
+ *
430
+ * @param request - The HTTP request
431
+ * @param options - Optional configuration including onFinish callback for persistence
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * // Basic usage
436
+ * return runtime.handleRequest(request);
437
+ *
438
+ * // With server-side persistence
439
+ * return runtime.handleRequest(request, {
440
+ * onFinish: async ({ messages, threadId }) => {
441
+ * await db.thread.upsert({
442
+ * where: { id: threadId },
443
+ * update: { messages, updatedAt: new Date() },
444
+ * create: { id: threadId, messages },
445
+ * });
446
+ * },
447
+ * });
448
+ * ```
449
+ */
450
+ handleRequest(request: Request, options?: HandleRequestOptions): Promise<Response>;
451
+ /**
452
+ * Wrap a generator to intercept the done event and call onFinish
390
453
  */
391
- handleRequest(request: Request): Promise<Response>;
454
+ private wrapGeneratorWithOnFinish;
392
455
  /**
393
456
  * Handle non-streaming request - returns JSON instead of SSE
394
457
  */
package/dist/index.js CHANGED
@@ -3432,8 +3432,28 @@ var Runtime = class {
3432
3432
  }
3433
3433
  /**
3434
3434
  * Handle HTTP request (for use with any framework)
3435
+ *
3436
+ * @param request - The HTTP request
3437
+ * @param options - Optional configuration including onFinish callback for persistence
3438
+ *
3439
+ * @example
3440
+ * ```typescript
3441
+ * // Basic usage
3442
+ * return runtime.handleRequest(request);
3443
+ *
3444
+ * // With server-side persistence
3445
+ * return runtime.handleRequest(request, {
3446
+ * onFinish: async ({ messages, threadId }) => {
3447
+ * await db.thread.upsert({
3448
+ * where: { id: threadId },
3449
+ * update: { messages, updatedAt: new Date() },
3450
+ * create: { id: threadId, messages },
3451
+ * });
3452
+ * },
3453
+ * });
3454
+ * ```
3435
3455
  */
3436
- async handleRequest(request) {
3456
+ async handleRequest(request, options) {
3437
3457
  try {
3438
3458
  const body = await request.json();
3439
3459
  if (this.config.debug) {
@@ -3447,11 +3467,17 @@ var Runtime = class {
3447
3467
  body,
3448
3468
  signal,
3449
3469
  useAgentLoop || false,
3450
- request
3470
+ request,
3471
+ options
3451
3472
  );
3452
3473
  }
3453
3474
  const generator = useAgentLoop ? this.processChatWithLoop(body, signal, void 0, void 0, request) : this.processChat(body, signal);
3454
- return createSSEResponse(generator);
3475
+ const wrappedGenerator = this.wrapGeneratorWithOnFinish(
3476
+ generator,
3477
+ body.threadId,
3478
+ options
3479
+ );
3480
+ return createSSEResponse(wrappedGenerator);
3455
3481
  } catch (error) {
3456
3482
  console.error("[Copilot SDK] Error:", error);
3457
3483
  return new Response(
@@ -3465,10 +3491,34 @@ var Runtime = class {
3465
3491
  );
3466
3492
  }
3467
3493
  }
3494
+ /**
3495
+ * Wrap a generator to intercept the done event and call onFinish
3496
+ */
3497
+ async *wrapGeneratorWithOnFinish(generator, threadId, options) {
3498
+ let doneMessages;
3499
+ for await (const event of generator) {
3500
+ if (event.type === "done" && event.messages) {
3501
+ doneMessages = event.messages;
3502
+ }
3503
+ yield event;
3504
+ }
3505
+ if (options?.onFinish && doneMessages) {
3506
+ try {
3507
+ const result = {
3508
+ messages: doneMessages,
3509
+ threadId
3510
+ // TODO: Add usage tracking when available from adapter
3511
+ };
3512
+ await options.onFinish(result);
3513
+ } catch (error) {
3514
+ console.error("[Copilot SDK] onFinish callback error:", error);
3515
+ }
3516
+ }
3517
+ }
3468
3518
  /**
3469
3519
  * Handle non-streaming request - returns JSON instead of SSE
3470
3520
  */
3471
- async handleNonStreamingRequest(body, signal, useAgentLoop, httpRequest) {
3521
+ async handleNonStreamingRequest(body, signal, useAgentLoop, httpRequest, options) {
3472
3522
  try {
3473
3523
  const generator = useAgentLoop ? this.processChatWithLoop(
3474
3524
  body,
@@ -3520,6 +3570,20 @@ var Runtime = class {
3520
3570
  break;
3521
3571
  }
3522
3572
  }
3573
+ if (options?.onFinish && messages && !error) {
3574
+ try {
3575
+ const result = {
3576
+ messages,
3577
+ threadId: body.threadId
3578
+ };
3579
+ await options.onFinish(result);
3580
+ } catch (callbackError) {
3581
+ console.error(
3582
+ "[Copilot SDK] onFinish callback error:",
3583
+ callbackError
3584
+ );
3585
+ }
3586
+ }
3523
3587
  const response = {
3524
3588
  success: !error,
3525
3589
  content,