playkit-sdk 1.4.0-beta.2 → 1.4.0-beta.3

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
@@ -68,6 +68,33 @@ await chat.chatStream(
68
68
  );
69
69
  ```
70
70
 
71
+ ### Reasoning (Thinking)
72
+
73
+ Reasoning-capable models can think before answering. Enable it with the
74
+ `thinking` option (set the `effort` level) and read the model's reasoning
75
+ separately from its answer.
76
+
77
+ ```typescript
78
+ // Non-streaming: reasoning is returned on `result.reasoning`
79
+ const result = await chat.textGeneration({
80
+ messages: [{ role: 'user', content: 'Solve: 17 * 24, show your work.' }],
81
+ thinking: { effort: 'high' },
82
+ });
83
+
84
+ console.log('Answer:', result.content);
85
+ console.log('Reasoning:', result.reasoning);
86
+
87
+ // Streaming: reasoning arrives via the `onReasoning` callback,
88
+ // kept separate from the answer text in `onChunk`
89
+ await chat.textGenerationStream({
90
+ messages: [{ role: 'user', content: 'Solve: 17 * 24, show your work.' }],
91
+ thinking: { effort: 'high' },
92
+ onReasoning: (chunk) => process.stdout.write(`[thinking] ${chunk}`),
93
+ onChunk: (chunk) => process.stdout.write(chunk),
94
+ onComplete: (fullText) => console.log('\nComplete:', fullText),
95
+ });
96
+ ```
97
+
71
98
  ### Image Generation
72
99
 
73
100
  ```typescript
@@ -256,6 +283,10 @@ This SDK is proprietary software owned by Agentland Lab. Use of this SDK is subj
256
283
 
257
284
  ## Changelog
258
285
 
286
+ ### 1.4.0-beta.3
287
+ - Added `thinking` reasoning-effort option on chat (`thinking: { effort: 'high' }`)
288
+ - Surface model reasoning: `result.reasoning` (non-streaming) and the `onReasoning` callback (streaming)
289
+
259
290
  ### 1.0.0-beta.1
260
291
  - Initial public beta release
261
292
  - AI chat support (text generation)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * playkit-sdk v1.4.0-beta.2
2
+ * playkit-sdk v1.4.0-beta.3
3
3
  * PlayKit SDK for JavaScript
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  */
@@ -830,7 +830,7 @@ class TokenStorage {
830
830
  }
831
831
 
832
832
  const SDK_TYPE = 'Javascript';
833
- const SDK_VERSION = '"1.4.0-beta.2"';
833
+ const SDK_VERSION = '"1.4.0-beta.3"';
834
834
  function getSDKHeaders() {
835
835
  return {
836
836
  'X-SDK-Type': SDK_TYPE,
@@ -3930,6 +3930,9 @@ class ChatProvider {
3930
3930
  stop: chatConfig.stop || null,
3931
3931
  top_p: chatConfig.topP || null,
3932
3932
  };
3933
+ if (chatConfig.thinking) {
3934
+ requestBody.thinking = chatConfig.thinking;
3935
+ }
3933
3936
  try {
3934
3937
  const response = await fetch(`${this.baseURL}${endpoint}`, {
3935
3938
  method: 'POST',
@@ -3987,6 +3990,9 @@ class ChatProvider {
3987
3990
  stop: chatConfig.stop || null,
3988
3991
  top_p: chatConfig.topP || null,
3989
3992
  };
3993
+ if (chatConfig.thinking) {
3994
+ requestBody.thinking = chatConfig.thinking;
3995
+ }
3990
3996
  try {
3991
3997
  const response = await fetch(`${this.baseURL}${endpoint}`, {
3992
3998
  method: 'POST',
@@ -4051,6 +4057,9 @@ class ChatProvider {
4051
4057
  if (chatConfig.tool_choice) {
4052
4058
  requestBody.tool_choice = chatConfig.tool_choice;
4053
4059
  }
4060
+ if (chatConfig.thinking) {
4061
+ requestBody.thinking = chatConfig.thinking;
4062
+ }
4054
4063
  try {
4055
4064
  const response = await fetch(`${this.baseURL}${endpoint}`, {
4056
4065
  method: 'POST',
@@ -4109,6 +4118,9 @@ class ChatProvider {
4109
4118
  if (chatConfig.tool_choice) {
4110
4119
  requestBody.tool_choice = chatConfig.tool_choice;
4111
4120
  }
4121
+ if (chatConfig.thinking) {
4122
+ requestBody.thinking = chatConfig.thinking;
4123
+ }
4112
4124
  try {
4113
4125
  const response = await fetch(`${this.baseURL}${endpoint}`, {
4114
4126
  method: 'POST',
@@ -4656,6 +4668,7 @@ function createDecoder() {
4656
4668
  class StreamParser {
4657
4669
  /**
4658
4670
  * Parse SSE stream using ReadableStream
4671
+ * Yields typed parts so callers can separate text from reasoning.
4659
4672
  */
4660
4673
  static parseStream(reader) {
4661
4674
  return __asyncGenerator(this, arguments, function* parseStream_1() {
@@ -4686,9 +4699,9 @@ class StreamParser {
4686
4699
  const data = trimmed.substring(6); // Remove 'data: ' prefix
4687
4700
  try {
4688
4701
  const parsed = JSON.parse(data);
4689
- const text = this.extractTextFromChunk(parsed);
4690
- if (text) {
4691
- yield yield __await(text);
4702
+ const part = this.extractPartFromChunk(parsed);
4703
+ if (part) {
4704
+ yield yield __await(part);
4692
4705
  }
4693
4706
  // Stream termination events
4694
4707
  if (parsed.type === 'done' || parsed.type === 'finish' || parsed.finish_reason) {
@@ -4705,7 +4718,7 @@ class StreamParser {
4705
4718
  }
4706
4719
  catch (error) {
4707
4720
  // If JSON parse fails, treat as plain text
4708
- yield yield __await(data);
4721
+ yield yield __await({ kind: 'text', delta: data });
4709
4722
  }
4710
4723
  }
4711
4724
  }
@@ -4717,22 +4730,33 @@ class StreamParser {
4717
4730
  });
4718
4731
  }
4719
4732
  /**
4720
- * Extract text from a stream chunk
4721
- * Supports multiple formats (UI Message Stream and OpenAI)
4733
+ * Extract a typed part (text or reasoning) from a stream chunk
4734
+ * Supports multiple formats (UI Message Stream and OpenAI).
4735
+ * Reasoning is detected before the generic text fallback so thinking
4736
+ * deltas never leak into the text stream.
4722
4737
  */
4723
- static extractTextFromChunk(chunk) {
4724
- var _a, _b;
4725
- // UI Message Stream format: { type: "text-delta", delta: "..." }
4738
+ static extractPartFromChunk(chunk) {
4739
+ var _a, _b, _c, _d;
4740
+ // UI Message Stream reasoning: { type: "reasoning-delta", delta: "..." }
4741
+ if (chunk.type === 'reasoning-delta' && chunk.delta) {
4742
+ return { kind: 'reasoning', delta: chunk.delta };
4743
+ }
4744
+ // UI Message Stream text: { type: "text-delta", delta: "..." }
4726
4745
  if (chunk.type === 'text-delta' && chunk.delta) {
4727
- return chunk.delta;
4746
+ return { kind: 'text', delta: chunk.delta };
4728
4747
  }
4729
- // OpenAI format: { choices: [{ delta: { content: "..." } }] }
4730
- if (chunk.choices && ((_b = (_a = chunk.choices[0]) === null || _a === void 0 ? void 0 : _a.delta) === null || _b === void 0 ? void 0 : _b.content)) {
4731
- return chunk.choices[0].delta.content;
4748
+ // OpenAI reasoning (defensive): { choices: [{ delta: { reasoning_content: "..." } }] }
4749
+ if (chunk.choices && ((_b = (_a = chunk.choices[0]) === null || _a === void 0 ? void 0 : _a.delta) === null || _b === void 0 ? void 0 : _b.reasoning_content)) {
4750
+ return { kind: 'reasoning', delta: chunk.choices[0].delta.reasoning_content };
4732
4751
  }
4733
- // Direct delta format
4752
+ // OpenAI text: { choices: [{ delta: { content: "..." } }] }
4753
+ if (chunk.choices && ((_d = (_c = chunk.choices[0]) === null || _c === void 0 ? void 0 : _c.delta) === null || _d === void 0 ? void 0 : _d.content)) {
4754
+ return { kind: 'text', delta: chunk.choices[0].delta.content };
4755
+ }
4756
+ // Direct delta format (text)
4734
4757
  if (chunk.delta) {
4735
- return typeof chunk.delta === 'string' ? chunk.delta : chunk.delta.content || null;
4758
+ const text = typeof chunk.delta === 'string' ? chunk.delta : chunk.delta.content || null;
4759
+ return text ? { kind: 'text', delta: text } : null;
4736
4760
  }
4737
4761
  return null;
4738
4762
  }
@@ -4746,8 +4770,10 @@ class StreamParser {
4746
4770
  for (var _d = true, _e = __asyncValues(this.parseStream(reader)), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
4747
4771
  _c = _f.value;
4748
4772
  _d = false;
4749
- const chunk = _c;
4750
- fullText += chunk;
4773
+ const part = _c;
4774
+ if (part.kind === 'text') {
4775
+ fullText += part.delta;
4776
+ }
4751
4777
  }
4752
4778
  }
4753
4779
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -4761,8 +4787,9 @@ class StreamParser {
4761
4787
  }
4762
4788
  /**
4763
4789
  * Stream with callbacks
4790
+ * Text deltas go to onChunk; reasoning (thinking) deltas go to onReasoning.
4764
4791
  */
4765
- static async streamWithCallbacks(reader, onChunk, onComplete, onError) {
4792
+ static async streamWithCallbacks(reader, onChunk, onComplete, onError, onReasoning) {
4766
4793
  var _a, e_2, _b, _c;
4767
4794
  let fullText = '';
4768
4795
  try {
@@ -4770,9 +4797,15 @@ class StreamParser {
4770
4797
  for (var _d = true, _e = __asyncValues(this.parseStream(reader)), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
4771
4798
  _c = _f.value;
4772
4799
  _d = false;
4773
- const chunk = _c;
4774
- fullText += chunk;
4775
- onChunk(chunk);
4800
+ const part = _c;
4801
+ if (part.kind === 'reasoning') {
4802
+ if (onReasoning) {
4803
+ onReasoning(part.delta);
4804
+ }
4805
+ continue;
4806
+ }
4807
+ fullText += part.delta;
4808
+ onChunk(part.delta);
4776
4809
  }
4777
4810
  }
4778
4811
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
@@ -4873,6 +4906,7 @@ class ChatClient {
4873
4906
  : undefined,
4874
4907
  id: response.id,
4875
4908
  created: response.created,
4909
+ reasoning: choice.message.reasoning_content,
4876
4910
  };
4877
4911
  }
4878
4912
  /**
@@ -4881,7 +4915,7 @@ class ChatClient {
4881
4915
  async textGenerationStream(config) {
4882
4916
  const chatConfig = Object.assign(Object.assign({}, config), { model: config.model || this.model });
4883
4917
  const reader = await this.provider.chatCompletionStream(chatConfig);
4884
- await StreamParser.streamWithCallbacks(reader, config.onChunk, config.onComplete, config.onError);
4918
+ await StreamParser.streamWithCallbacks(reader, config.onChunk, config.onComplete, config.onError, config.onReasoning);
4885
4919
  }
4886
4920
  // ===== Structured Output Generation =====
4887
4921
  /**
@@ -5039,6 +5073,7 @@ class ChatClient {
5039
5073
  id: response.id,
5040
5074
  created: response.created,
5041
5075
  tool_calls: choice.message.tool_calls,
5076
+ reasoning: choice.message.reasoning_content,
5042
5077
  };
5043
5078
  }
5044
5079
  /**
@@ -5049,6 +5084,7 @@ class ChatClient {
5049
5084
  const chatConfig = Object.assign(Object.assign({}, config), { model: config.model || this.model });
5050
5085
  const reader = await this.provider.chatCompletionWithToolsStream(chatConfig);
5051
5086
  let fullContent = '';
5087
+ let fullReasoning = '';
5052
5088
  let toolCalls = [];
5053
5089
  await StreamParser.streamWithCallbacks(reader, (chunk) => {
5054
5090
  fullContent += chunk;
@@ -5061,9 +5097,14 @@ class ChatClient {
5061
5097
  model: chatConfig.model || this.model,
5062
5098
  finishReason: toolCalls.length > 0 ? 'tool_calls' : 'stop',
5063
5099
  tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
5100
+ reasoning: fullReasoning || undefined,
5064
5101
  });
5065
5102
  }
5066
- }, config.onError);
5103
+ }, config.onError, (chunk) => {
5104
+ var _a;
5105
+ fullReasoning += chunk;
5106
+ (_a = config.onReasoning) === null || _a === void 0 ? void 0 : _a.call(config, chunk);
5107
+ });
5067
5108
  }
5068
5109
  }
5069
5110