kash-shell 0.3.35__py3-none-any.whl → 0.3.36__py3-none-any.whl

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.
@@ -29,6 +29,7 @@ def windowed_llm_transform(
29
29
  windowing: WindowSettings | None,
30
30
  diff_filter: DiffFilter | None = None,
31
31
  check_no_results: bool = True,
32
+ enable_web_search: bool = False,
32
33
  ) -> TextDoc:
33
34
  def doc_transform(input_doc: TextDoc) -> TextDoc:
34
35
  return TextDoc.from_text(
@@ -41,6 +42,7 @@ def windowed_llm_transform(
41
42
  input=input_doc.reassemble(),
42
43
  body_template=template,
43
44
  check_no_results=check_no_results,
45
+ enable_web_search=enable_web_search,
44
46
  ).content
45
47
  )
46
48
  )
@@ -67,6 +69,7 @@ def llm_transform_str(options: LLMOptions, input_str: str, check_no_results: boo
67
69
  input_str,
68
70
  options.windowing,
69
71
  diff_filter=options.diff_filter,
72
+ enable_web_search=options.enable_web_search,
70
73
  ).reassemble()
71
74
  else:
72
75
  log.info(
@@ -81,6 +84,7 @@ def llm_transform_str(options: LLMOptions, input_str: str, check_no_results: boo
81
84
  body_template=options.body_template,
82
85
  input=input_str,
83
86
  check_no_results=check_no_results,
87
+ enable_web_search=options.enable_web_search,
84
88
  ).content
85
89
 
86
90
  return result_str
@@ -485,6 +485,9 @@ class FileStore(Workspace):
485
485
  If `with_sidematter` is true, will copy any sidematter files (metadata/assets) to
486
486
  the destination.
487
487
  """
488
+ # TODO: Make sure importing a text item that already has
489
+ # frontmatter doesn't accidentally duplicate the frontmatter
490
+
488
491
  from kash.file_storage.item_file_format import read_item
489
492
  from kash.web_content.canon_url import canonicalize_url
490
493
 
@@ -531,6 +534,7 @@ class FileStore(Workspace):
531
534
  # This will read the file with or without frontmatter.
532
535
  # We are importing so we want to drop the external path so we save the body.
533
536
  item = read_item(path, self.base_dir)
537
+ log.info("Imported text item: %s", item)
534
538
  item.external_path = None
535
539
 
536
540
  if item.type and as_type and item.type != as_type:
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import time
4
4
  from dataclasses import dataclass
5
- from typing import TYPE_CHECKING, cast
5
+ from typing import TYPE_CHECKING, Any, cast
6
6
 
7
7
  from flowmark import Wrap, fill_text
8
8
  from funlog import format_duration, log_calls
@@ -51,6 +51,7 @@ class LLMCompletionResult:
51
51
  message: LiteLLMMessage
52
52
  content: str
53
53
  citations: CitationList | None
54
+ tool_calls: list[dict[str, Any]] | None = None
54
55
 
55
56
  @property
56
57
  def content_with_citations(self) -> str:
@@ -59,40 +60,111 @@ class LLMCompletionResult:
59
60
  content = content + "\n\n" + self.citations.as_markdown_footnotes()
60
61
  return content
61
62
 
63
+ @property
64
+ def has_tool_calls(self) -> bool:
65
+ """Check if the response contains tool calls."""
66
+ return bool(self.tool_calls)
67
+
68
+ @property
69
+ def tool_call_names(self) -> list[str]:
70
+ """Get list of tool names that were called."""
71
+ if not self.tool_calls:
72
+ return []
73
+ names = []
74
+ for call in self.tool_calls:
75
+ # Handle both LiteLLM objects and dict representations
76
+ if hasattr(call, "function") and hasattr(getattr(call, "function", None), "name"):
77
+ # LiteLLM object format
78
+ names.append(f"{call.function.name}()") # pyright: ignore[reportAttributeAccessIssue]
79
+ elif isinstance(call, dict) and call.get("function", {}).get("name"):
80
+ # Dict format
81
+ names.append(f"{call['function']['name']}()")
82
+ else:
83
+ names.append(str(call))
84
+ return names
85
+
62
86
 
63
87
  @log_calls(level="info")
64
88
  def llm_completion(
65
89
  model: LLMName,
66
90
  messages: list[dict[str, str]],
67
91
  save_objects: bool = True,
68
- response_format: dict | type[BaseModel] | None = None,
92
+ response_format: dict[str, Any] | type[BaseModel] | None = None,
93
+ tools: list[dict[str, Any]] | None = None,
94
+ enable_web_search: bool = False,
69
95
  **kwargs,
70
96
  ) -> LLMCompletionResult:
71
97
  """
72
98
  Perform an LLM completion with LiteLLM.
99
+
100
+ Args:
101
+ model: The LLM model to use
102
+ messages: Chat messages
103
+ save_objects: Whether to save chat history
104
+ response_format: Response format specification
105
+ tools: List of tools available for function calling (e.g., web_search)
106
+ enable_web_search: If True, automatically add web search tools for the model
107
+ **kwargs: Additional LiteLLM parameters
73
108
  """
74
- import litellm
75
109
  from litellm.types.utils import Choices, ModelResponse
76
110
 
77
111
  init_litellm()
78
112
 
113
+ # Prepare completion parameters
114
+ completion_params = {
115
+ "model": model.litellm_name,
116
+ "messages": messages,
117
+ **kwargs,
118
+ }
119
+
120
+ # Auto-enable web search if requested
121
+ if enable_web_search:
122
+ import litellm
123
+
124
+ if litellm.supports_web_search(model=model.litellm_name):
125
+ log.message("Enabling web search for model %s", model.litellm_name)
126
+ completion_params["web_search_options"] = {"search_context_size": "medium"}
127
+ else:
128
+ log.warning("Web search requested but not supported by model %s", model.litellm_name)
129
+
79
130
  chat_history = ChatHistory.from_dicts(messages)
131
+
132
+ # Enhanced logging to detect tool use
133
+ tools_info = f", {len(tools)} tools" if tools else ", no tools"
80
134
  log.info(
81
- "Calling LLM completion from %s on %s, response_format=%s",
135
+ "Calling LLM completion from %s on %s, response_format=%s%s",
82
136
  model.litellm_name,
83
137
  chat_history.size_summary(),
84
138
  response_format,
139
+ tools_info,
85
140
  )
86
141
 
142
+ if tools:
143
+ tool_names = []
144
+ for tool in tools:
145
+ if tool.get("type") == "function":
146
+ tool_names.append(tool.get("function", {}).get("name", "unknown"))
147
+ elif tool.get("type") == "native_web_search":
148
+ tool_names.append("native_web_search")
149
+ else:
150
+ tool_names.append(tool.get("type", "unknown"))
151
+
152
+ log.message("Tools enabled: %s", tool_names)
153
+
87
154
  start_time = time.time()
155
+
156
+ if response_format:
157
+ completion_params["response_format"] = response_format
158
+
159
+ if tools:
160
+ completion_params["tools"] = tools
161
+ log.info("Enabling function calling with %d tools", len(tools))
162
+
163
+ import litellm
164
+
88
165
  llm_output = cast(
89
166
  ModelResponse,
90
- litellm.completion(
91
- model.litellm_name,
92
- messages=messages,
93
- response_format=response_format,
94
- **kwargs,
95
- ), # pyright: ignore
167
+ litellm.completion(**completion_params), # pyright: ignore
96
168
  )
97
169
  elapsed = time.time() - start_time
98
170
 
@@ -100,23 +172,47 @@ def llm_completion(
100
172
 
101
173
  message = choices.message
102
174
 
175
+ # Extract tool calls from the response
176
+ tool_calls = getattr(message, "tool_calls", None)
177
+ tool_calls_list = list(tool_calls) if tool_calls else None
178
+
103
179
  # Just sanity checking and logging.
104
180
  content = choices.message.content
105
181
  if not content or not isinstance(content, str):
106
182
  raise ApiResultError(f"LLM completion failed: {model.litellm_name}: {llm_output}")
107
183
 
184
+ # Create the result object with tool calls
185
+ citations = llm_output.get("citations", None)
186
+ result = LLMCompletionResult(
187
+ message=message,
188
+ content=content,
189
+ citations=CitationList(citations=citations) if citations else None,
190
+ tool_calls=tool_calls_list,
191
+ )
192
+
193
+ # Log tool calls if present
194
+ if result.has_tool_calls:
195
+ tool_count = len(result.tool_calls or [])
196
+ log.message("LLM executed %d function calls: %s", tool_count, result.tool_call_names)
197
+ log.message(
198
+ "⚠️ Function calls require implementation - LLM requested tools but no handlers are implemented"
199
+ )
200
+
201
+ # Performance logging
108
202
  total_input_len = sum(len(m["content"]) for m in messages)
109
203
  speed = len(content) / elapsed
204
+ tool_count = len(result.tool_calls or []) if result.has_tool_calls else 0
205
+ tool_info = f", {tool_count} tool calls" if result.has_tool_calls else ""
110
206
  log.info(
111
207
  f"{EMOJI_TIMING} LLM completion from {model.litellm_name} in {format_duration(elapsed)}: "
112
208
  f"input {total_input_len} chars in {len(messages)} messages, output {len(content)} chars "
113
- f"({speed:.0f} char/s)"
209
+ f"({speed:.0f} char/s){tool_info}"
114
210
  )
115
211
 
116
- citations = llm_output.get("citations", None)
117
-
118
212
  if save_objects:
119
213
  metadata = {"citations": citations} if citations else {}
214
+ if result.has_tool_calls:
215
+ metadata["tool_calls"] = len(result.tool_calls or [])
120
216
  chat_history.messages.append(
121
217
  ChatMessage(role=ChatRole.assistant, content=content, metadata=metadata)
122
218
  )
@@ -128,11 +224,7 @@ def llm_completion(
128
224
  file_ext="yml",
129
225
  )
130
226
 
131
- return LLMCompletionResult(
132
- message=message,
133
- content=content,
134
- citations=CitationList(citations=citations) if citations else None,
135
- )
227
+ return result
136
228
 
137
229
 
138
230
  def llm_template_completion(
@@ -143,7 +235,9 @@ def llm_template_completion(
143
235
  previous_messages: list[dict[str, str]] | None = None,
144
236
  save_objects: bool = True,
145
237
  check_no_results: bool = True,
146
- response_format: dict | type[BaseModel] | None = None,
238
+ response_format: dict[str, Any] | type[BaseModel] | None = None,
239
+ tools: list[dict[str, Any]] | None = None,
240
+ enable_web_search: bool = False,
147
241
  **kwargs,
148
242
  ) -> LLMCompletionResult:
149
243
  """
@@ -169,6 +263,8 @@ def llm_template_completion(
169
263
  ],
170
264
  save_objects=save_objects,
171
265
  response_format=response_format,
266
+ tools=tools,
267
+ enable_web_search=enable_web_search,
172
268
  **kwargs,
173
269
  )
174
270
 
kash/llm_utils/llms.py CHANGED
@@ -28,22 +28,23 @@ class LLM(LLMName, Enum):
28
28
  gpt_4_1 = LLMName("gpt-4.1")
29
29
  gpt_4o = LLMName("gpt-4o")
30
30
  gpt_4o_mini = LLMName("gpt-4o-mini")
31
+ gpt_4o_search_preview = LLMName("gpt-4o-search-preview")
31
32
  gpt_4 = LLMName("gpt-4")
32
33
  gpt_4_1_mini = LLMName("gpt-4.1-mini")
33
34
  gpt_4_1_nano = LLMName("gpt-4.1-nano")
34
35
 
35
- # https://docs.anthropic.com/en/docs/about-claude/models/all-models
36
+ # https://docs.claude.com/en/docs/about-claude/models
36
37
 
37
- claude_4_1_opus = LLMName("claude-opus-4-1")
38
- claude_4_opus = LLMName("claude-opus-4-20250514")
39
- claude_4_sonnet = LLMName("claude-sonnet-4-20250514")
40
- claude_3_7_sonnet = LLMName("claude-3-7-sonnet-latest")
41
- claude_3_5_haiku = LLMName("claude-3-5-haiku-latest")
38
+ claude_sonnet_4_5 = LLMName("claude-sonnet-4-5-20250929")
39
+ claude_haiku_4_5 = LLMName("claude-haiku-4-5-20251001")
40
+ claude_opus_4_1 = LLMName("claude-opus-4-1-20250805")
41
+ claude_sonnet_4 = LLMName("claude-sonnet-4-20250514")
42
+ claude_opus_4 = LLMName("claude-opus-4-20250514")
42
43
 
43
44
  # https://ai.google.dev/gemini-api/docs/models
44
45
  gemini_2_5_pro = LLMName("gemini/gemini-2.5-pro")
45
46
  gemini_2_5_flash = LLMName("gemini/gemini-2.5-flash")
46
- gemini_2_5_flash_lite = LLMName("gemini-2.5-flash-lite-preview-06-17")
47
+ gemini_2_5_flash_lite = LLMName("gemini/gemini-2.5-flash-lite")
47
48
 
48
49
  # https://docs.x.ai/docs/models
49
50
  xai_grok_3 = LLMName("xai/grok-3")
@@ -171,6 +171,7 @@ class LLMOptions:
171
171
  body_template: MessageTemplate = MessageTemplate("{body}")
172
172
  windowing: WindowSettings = WINDOW_NONE
173
173
  diff_filter: DiffFilter | None = None
174
+ enable_web_search: bool = False
174
175
 
175
176
  def updated_with(self, param_name: str, value: Any) -> LLMOptions:
176
177
  """Update option from an action parameter."""
@@ -543,8 +544,8 @@ class Action(ABC):
543
544
  def preassemble_result(self, context: ActionContext) -> ActionResult | None:
544
545
  """
545
546
  Actions can have a separate preliminary step to pre-assemble outputs. This allows
546
- us to determine the title and types for the output items and check if they were
547
- already generated before running slow or expensive actions.
547
+ us to determine thew expected shape of the expected output and check if it already
548
+ exists.
548
549
 
549
550
  For now, this only applies to actions with a single output, when `self.cacheable`
550
551
  is True.
@@ -568,7 +569,10 @@ class Action(ABC):
568
569
  self.name,
569
570
  )
570
571
  output_type = ItemType.doc
571
- primary_output = primary_input.derived_copy(context, 0, type=output_type)
572
+ output_format = context.action.output_format or primary_input.format
573
+ primary_output = primary_input.derived_copy(
574
+ context, 0, type=output_type, format=output_format
575
+ )
572
576
  log.info("Preassembled output: source %s, %s", primary_output.source, primary_output)
573
577
  return ActionResult([primary_output])
574
578
  else:
kash/model/items_model.py CHANGED
@@ -193,9 +193,16 @@ class ItemId:
193
193
  from kash.web_content.canon_url import canonicalize_url
194
194
 
195
195
  item_id = None
196
- if item.type == ItemType.resource and item.format == Format.url and item.url:
196
+ if (
197
+ item.type == ItemType.resource
198
+ and item.format == Format.url
199
+ and item.url
200
+ and not item.source
201
+ ):
202
+ # This is a plain URL resource, so its identity is its URL.
197
203
  item_id = ItemId(item.type, IdType.url, canonicalize_url(item.url))
198
204
  elif item.type == ItemType.concept and item.title:
205
+ # This is a concept, so its identity is its title.
199
206
  item_id = ItemId(item.type, IdType.concept, canonicalize_concept(item.title))
200
207
  elif item.source and item.source.cacheable and item.source.operation.has_known_inputs:
201
208
  # We know the source of this and if the action was cacheable, we can create
@@ -206,10 +206,10 @@ A list of parameter declarations, possibly with default values.
206
206
 
207
207
  # These are the default models for typical use cases.
208
208
  # The user may override them with parameters.
209
- DEFAULT_CAREFUL_LLM = LLM.gpt_5
210
- DEFAULT_STRUCTURED_LLM = LLM.gpt_5
211
- DEFAULT_STANDARD_LLM = LLM.gpt_5
212
- DEFAULT_FAST_LLM = LLM.gpt_5_mini
209
+ DEFAULT_CAREFUL_LLM = LLM.claude_sonnet_4_5
210
+ DEFAULT_STRUCTURED_LLM = LLM.claude_sonnet_4_5
211
+ DEFAULT_STANDARD_LLM = LLM.claude_sonnet_4_5
212
+ DEFAULT_FAST_LLM = LLM.claude_haiku_4_5
213
213
 
214
214
 
215
215
  # Parameters set globally such as in the workspace.
@@ -1,8 +1,9 @@
1
1
  {% extends "simple_webpage.html.jinja" %}
2
2
 
3
3
  {#
4
- Extends the simple page with a right-side YouTube popover player.
5
- Usage: pass page_template="youtube_webpage.html.jinja" to simple_webpage_render.
4
+ Extends the simple page with YouTube popover player.
5
+ Safe to use instead of simple_webpage.html.jinja since it only adds
6
+ functionality for YouTube if applicable.
6
7
  #}
7
8
 
8
9
  {% block custom_styles %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.35
3
+ Version: 0.3.36
4
4
  Summary: The knowledge agent shell (core)
5
5
  Project-URL: Repository, https://github.com/jlevy/kash-shell
6
6
  Author-email: Joshua Levy <joshua@cal.berkeley.edu>
@@ -97,7 +97,7 @@ kash/exec/command_registry.py,sha256=1s2ogU8b8nqK_AEtslbr1eYrXCGDkeT30UrB7L0BRoM
97
97
  kash/exec/fetch_url_items.py,sha256=Bb8i9YW_XfJHwIAh5yf2_zLXagyESkQF1LL1uNaQQx0,6345
98
98
  kash/exec/history.py,sha256=l2XwHGBR1UgTGSFPSBE9mltmxvjR_5qFFO6d-Z008nc,1208
99
99
  kash/exec/importing.py,sha256=xunmBapeUMNc6Zox7y6e_DZkidyWeouiFZpphajwSzc,1843
100
- kash/exec/llm_transforms.py,sha256=jQAnxHhcvF3oILjpSHx0YRw8Qw-ZnioukXaJuaqjNVk,4626
100
+ kash/exec/llm_transforms.py,sha256=2fxas6K2YcixVGpXKt0-nxlN2qc1SR3-O1KbE0sFKIg,4834
101
101
  kash/exec/precondition_checks.py,sha256=HymxL7qm4Yz8V76Um5pKdIRnQ2N-p9rpQQi1fI38bNA,2139
102
102
  kash/exec/precondition_registry.py,sha256=9O-01d2OrsYLuhqodVuWjouLR2ABJbUotAmfJNBCRzs,1439
103
103
  kash/exec/preconditions.py,sha256=bwNuuPEnkymj24ySPTl8K5DEgTtB2NPGAm9cWaomhAk,5262
@@ -110,7 +110,7 @@ kash/exec_model/commands_model.py,sha256=iM8QhzA0tAas5OwF5liUfHtm45XIH1LcvCviuh3
110
110
  kash/exec_model/script_model.py,sha256=1VG3LhkTmlKzHOYouZ92ZpOSKSCcsz3-tHNcFMQF788,5031
111
111
  kash/exec_model/shell_model.py,sha256=LUhQivbpXlerM-DUzNY7BtctNBbn08Wto8CSSxQDxRU,568
112
112
  kash/file_storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- kash/file_storage/file_store.py,sha256=rWFJD_PVzNgBtFBUD8Ltj9GK-am5zFj9vrMdyIy9pjQ,31442
113
+ kash/file_storage/file_store.py,sha256=0re_Gp0NoN3KxsMPtU8RSrG3Jw_PelC2wqju07AGxTU,31634
114
114
  kash/file_storage/item_file_format.py,sha256=QNNpvMDDNyBLLrIwy3yhNgN0Ktsvjh-_Uzkf2XQpI98,7531
115
115
  kash/file_storage/item_id_index.py,sha256=aiDHomizFLO_Ui2i6n-YIF4RUosIsxRIQca35yCdIIk,4589
116
116
  kash/file_storage/metadata_dirs.py,sha256=9AqO3S3SSY1dtvP2iLX--E4ui0VIzXttG8R040otfyg,3820
@@ -135,10 +135,10 @@ kash/llm_utils/custom_sliding_transforms.py,sha256=z07WCdBoiywBIGk2EXK3xY4t_6g8I
135
135
  kash/llm_utils/fuzzy_parsing.py,sha256=bbG2Y7i5w6kxAVPAixyluv3MDS2hW_pkhnJpVOLHZQc,3278
136
136
  kash/llm_utils/init_litellm.py,sha256=5Fn9uW4P7lfEO8Rk1EJJUzDEGNjw-PDvxFgHlKDf-Ok,409
137
137
  kash/llm_utils/llm_api_keys.py,sha256=nTB9wSFfHTOXvqshSQCQGCPxUwOW1U7oslngya8nHkw,1168
138
- kash/llm_utils/llm_completion.py,sha256=SzeWGRrsjuN1TXdPwscYG6whLQkHclITtwTvQK19GE0,5436
138
+ kash/llm_utils/llm_completion.py,sha256=UNFNgJbgU8sAWXmSrMV9DGrQ_1x-0IeEbtvrDG_P4NE,9251
139
139
  kash/llm_utils/llm_messages.py,sha256=70QwIIvdwo-h4Jfn_6MbEHb3LTUjUmzg_v_dU_Ey__g,1174
140
140
  kash/llm_utils/llm_names.py,sha256=VZbdKnoeBx_luB5YQ-Rz37gMt3_FcueJdp40ZaQbpUA,3620
141
- kash/llm_utils/llms.py,sha256=S4hBDeOraKOp9e99M8Ga61u6xAkocxs02jXgJRdFNSA,3983
141
+ kash/llm_utils/llms.py,sha256=sGDrTnYAqjg_keKhXa7JR3HHkp5Klt-OhO3t9YjuhVQ,4036
142
142
  kash/local_server/__init__.py,sha256=AyNpvCOJlQF6A4DnlYKRMbbfRNzdizEA-ytp-F2SLZU,162
143
143
  kash/local_server/local_server.py,sha256=EugjL30VM0pWdZDsiQxU-o6EdEa082qlGd_7RHvI5tk,5863
144
144
  kash/local_server/local_server_commands.py,sha256=T5wN-Xty3IbwbyeJxTULPB2NqssWLJcuV8IoqMu9bus,1668
@@ -164,18 +164,18 @@ kash/media_base/transcription_format.py,sha256=rOVPTpwvW22c27BRwYF-Tc_xzqK_wOtUZ
164
164
  kash/media_base/transcription_whisper.py,sha256=GqvroW9kBAH4-gcbYkMgNCfs2MpMIgm1ip3NMWtJ0IE,1169
165
165
  kash/media_base/services/local_file_media.py,sha256=_NV-T90rShJ8ucUjQXMPCKKJ50GSFE9PyyVzhXp5z9w,5624
166
166
  kash/model/__init__.py,sha256=kFfBKb5N70NWYUfpRRxn_Sb9p_vXlB6BBaTCqWmSReo,2978
167
- kash/model/actions_model.py,sha256=Y_MyZ6ATxr7-0AAnBFyWOJ8_81DCeWviNc2U4ig59bM,23705
167
+ kash/model/actions_model.py,sha256=I87Gb2nU6xelEuM8WFuuHWDqczjnlbpBYkw6wWIYkbo,23825
168
168
  kash/model/assistant_response_model.py,sha256=6eDfC27nyuBDFjv5nCYMa_Qb2mPbKwDzZy7uLOIyskI,2653
169
169
  kash/model/compound_actions_model.py,sha256=oYEtVKtQv-mA1abZkK7PvaM9xazVBUuk1z0geKBulak,6965
170
170
  kash/model/concept_model.py,sha256=we2qOcy9Mv1q7XPfkDLp_CyO_-8DwAUfUYlpgy_jrFs,1011
171
171
  kash/model/exec_model.py,sha256=3Su3NEmEtDoSuQSxvg75FYY_EdClSM5pwQK1i7_S88A,3131
172
172
  kash/model/graph_model.py,sha256=T034y0E9OJtITd1g9zp9vll5pLscdatq6JoT08KvPZE,2724
173
- kash/model/items_model.py,sha256=1WXNNmiqDs32XR3d8v_dUY4Y6T-3ow3XKuTJOoF_how,39937
173
+ kash/model/items_model.py,sha256=e-KCVhC6poWjocsxZVBa0A8gmehtsZRcIqhLVIna5Ho,40152
174
174
  kash/model/language_list.py,sha256=I3RIbxTseVmPdhExQimimEv18Gmy2ImMbpXe0-_t1Qw,450
175
175
  kash/model/llm_actions_model.py,sha256=a29uXVNfS2CiqvM7HPdC6H9A23rSQQihAideuBLMH8g,2110
176
176
  kash/model/media_model.py,sha256=ZnlZ-FkswbAIGpUAuNqLce1WDZK-WbnwHn2ipg8x7-0,3511
177
177
  kash/model/operations_model.py,sha256=WmU-xeWGsqMLVN369dQEyVGU8T7G_KyLLsj6YFc5sVw,6517
178
- kash/model/params_model.py,sha256=NHW-74_sFCY58spf9bzU1EaVxLDpdbqmiw8SCSKASCw,15079
178
+ kash/model/params_model.py,sha256=PWyx2P9tt1zj8NpBnvFkn61_KCegFtTJ_FSPYSLnsiY,15121
179
179
  kash/model/paths_model.py,sha256=KDFm7wan7hjObHbnV2rR8-jsyLTVqbKcwFdKeLFRtdM,15889
180
180
  kash/model/preconditions_model.py,sha256=-IfsVR0NkQhq_3hUTXzK2bFYAd--3YjSwUiDKHVQQqk,2887
181
181
  kash/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -277,7 +277,7 @@ kash/web_gen/templates/explain_view.html.jinja,sha256=DNw5Iw5SrhIUFRGB4qNvfcKXsB
277
277
  kash/web_gen/templates/item_view.html.jinja,sha256=_b51RuoBmYu7nxVq-S_zw_tv8mfQXHICGqfDWNIB9Xg,7304
278
278
  kash/web_gen/templates/simple_webpage.html.jinja,sha256=_RVu0AvrN5fK_Kz-tEi4AlPQ_wuu8-S9oFIYg_sdcec,2556
279
279
  kash/web_gen/templates/tabbed_webpage.html.jinja,sha256=umkipUXW-lDGnbV-tlDroCfCx_385PFnpbzsvwmityo,1843
280
- kash/web_gen/templates/youtube_webpage.html.jinja,sha256=uUdu3HWv0lwwgEh094QbzzesxAdYv9rCxCkiuuIr1MY,1380
280
+ kash/web_gen/templates/youtube_webpage.html.jinja,sha256=eEvWXQsqEIapH0-0nXfG1SGh4BAmbxKIMmvZMcteYQE,1397
281
281
  kash/web_gen/templates/components/toc_scripts.js.jinja,sha256=9AanLJaVormGi52h-k2tKJTRT4BiBGGNnw3Kmrnr40Q,10481
282
282
  kash/web_gen/templates/components/toc_styles.css.jinja,sha256=SM99C9bOu11qdZ1U6hN7lLe2w_Hk6u9qNZcx2knSkgg,7553
283
283
  kash/web_gen/templates/components/tooltip_scripts.js.jinja,sha256=63HUSXtT07Vh2ndp90ViuPHTdzslrkGO5it4s-5EheM,40181
@@ -305,8 +305,8 @@ kash/xonsh_custom/xonsh_modern_tools.py,sha256=mj_b34LZXfE8MJe9EpDmp5JZ0tDM1biYN
305
305
  kash/xonsh_custom/xonsh_ranking_completer.py,sha256=ZRGiAfoEgqgnlq2-ReUVEaX5oOgW1DQ9WxIv2OJLuTo,5620
306
306
  kash/xontrib/fnm.py,sha256=V2tsOdmIDgbFbZSfMLpsvDIwwJJqiYnOkOySD1cXNXw,3700
307
307
  kash/xontrib/kash_extension.py,sha256=FLIMlgR3C_6A1fwKE-Ul0nmmpJSszVPbAriinUyQ8Zg,1896
308
- kash_shell-0.3.35.dist-info/METADATA,sha256=tiHz-9gjkl9cyzEt8XxLl7kHDYbCb86dW9xpeU7qSGg,33581
309
- kash_shell-0.3.35.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
310
- kash_shell-0.3.35.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
311
- kash_shell-0.3.35.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
312
- kash_shell-0.3.35.dist-info/RECORD,,
308
+ kash_shell-0.3.36.dist-info/METADATA,sha256=LK3nnR0TWHtw_F8qG9WSihteRlQZXggGY8f-DwtUjBQ,33581
309
+ kash_shell-0.3.36.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
310
+ kash_shell-0.3.36.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
311
+ kash_shell-0.3.36.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
312
+ kash_shell-0.3.36.dist-info/RECORD,,