genkit 0.5.2__tar.gz → 0.6.0__tar.gz

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.
Files changed (111) hide show
  1. {genkit-0.5.2 → genkit-0.6.0}/PKG-INFO +5 -5
  2. {genkit-0.5.2 → genkit-0.6.0}/pyproject.toml +5 -5
  3. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/__init__.py +13 -5
  4. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_aio.py +145 -104
  5. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_embedding.py +3 -3
  6. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_evaluator.py +7 -5
  7. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_generate.py +281 -100
  8. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_model.py +2 -3
  9. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_prompt.py +235 -217
  10. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_resource.py +1 -1
  11. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_testing.py +3 -4
  12. genkit-0.6.0/src/genkit/_ai/_tools.py +450 -0
  13. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_action.py +179 -164
  14. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_dap.py +30 -6
  15. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_error.py +9 -0
  16. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_flow.py +3 -3
  17. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_plugin.py +8 -2
  18. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_reflection.py +34 -53
  19. genkit-0.6.0/src/genkit/_core/_reflection_v2.py +548 -0
  20. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_registry.py +306 -133
  21. genkit-0.6.0/src/genkit/_core/_tracing.py +197 -0
  22. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_typing.py +19 -38
  23. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/plugin_api/__init__.py +2 -1
  24. genkit-0.6.0/tests/genkit/ai/_tools_test.py +296 -0
  25. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/ai_plugin_test.py +4 -4
  26. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/ai_registry_test.py +1 -1
  27. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/dap_test.py +22 -9
  28. genkit-0.6.0/tests/genkit/ai/dynamic_tools_generate_test.py +303 -0
  29. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/embedding_test.py +3 -3
  30. genkit-0.6.0/tests/genkit/ai/generate_helpers_test.py +90 -0
  31. genkit-0.6.0/tests/genkit/ai/generate_interrupt_resume_test.py +762 -0
  32. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/generate_test.py +190 -0
  33. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/genkit_api_test.py +1 -38
  34. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/model_test.py +1 -1
  35. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/prompt_test.py +41 -18
  36. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/resource_integration_test.py +1 -47
  37. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/action_test.py +11 -0
  38. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/endpoints/reflection_test.py +20 -20
  39. genkit-0.6.0/tests/genkit/core/reflection_v2_test.py +532 -0
  40. genkit-0.6.0/tests/genkit/core/registry_test.py +432 -0
  41. genkit-0.6.0/tests/genkit/core/run_in_new_span_test.py +278 -0
  42. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/veneer/veneer_test.py +14 -12
  43. genkit-0.5.2/src/genkit/_ai/_tools.py +0 -147
  44. genkit-0.5.2/src/genkit/_core/_tracing.py +0 -117
  45. genkit-0.5.2/tests/genkit/core/registry_test.py +0 -141
  46. {genkit-0.5.2 → genkit-0.6.0}/.gitignore +0 -0
  47. {genkit-0.5.2 → genkit-0.6.0}/LICENSE +0 -0
  48. {genkit-0.5.2 → genkit-0.6.0}/README.md +0 -0
  49. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_decorators.py +0 -0
  50. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/__init__.py +0 -0
  51. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_array.py +0 -0
  52. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_enum.py +0 -0
  53. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_json.py +0 -0
  54. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_jsonl.py +0 -0
  55. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_schema.py +0 -0
  56. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_text.py +0 -0
  57. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_formats/_types.py +0 -0
  58. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_messages.py +0 -0
  59. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_middleware.py +0 -0
  60. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_ai/_runtime.py +0 -0
  61. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_background.py +0 -0
  62. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_base.py +0 -0
  63. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_channel.py +0 -0
  64. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_compat.py +0 -0
  65. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_constants.py +0 -0
  66. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_context.py +0 -0
  67. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_environment.py +0 -0
  68. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_extract_json.py +0 -0
  69. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_http_client.py +0 -0
  70. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_logger.py +0 -0
  71. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_loop_cache.py +0 -0
  72. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_model.py +0 -0
  73. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_plugins.py +0 -0
  74. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_schema.py +0 -0
  75. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_trace/_adjusting_exporter.py +0 -0
  76. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_trace/_default_exporter.py +0 -0
  77. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_trace/_path.py +0 -0
  78. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_trace/_realtime_processor.py +0 -0
  79. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/_core/_trace/_suppress.py +0 -0
  80. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/embedder/__init__.py +0 -0
  81. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/evaluator/__init__.py +0 -0
  82. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/model/__init__.py +0 -0
  83. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/plugins/__init__.py +0 -0
  84. {genkit-0.5.2 → genkit-0.6.0}/src/genkit/py.typed +0 -0
  85. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/document_test.py +0 -0
  86. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/array_test.py +0 -0
  87. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/enum_test.py +0 -0
  88. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/formats_test.py +0 -0
  89. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/json_test.py +0 -0
  90. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/jsonl_test.py +0 -0
  91. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/formats/text_test.py +0 -0
  92. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/generate_operation_test.py +0 -0
  93. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/message_utils_test.py +0 -0
  94. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/middleware_test.py +0 -0
  95. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/ai/resource_test.py +0 -0
  96. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/channel_test.py +0 -0
  97. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/environment_test.py +0 -0
  98. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/error_test.py +0 -0
  99. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/extract_test.py +0 -0
  100. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/http_client_test.py +0 -0
  101. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/latency_test.py +0 -0
  102. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/schema_test.py +0 -0
  103. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/status_types_test.py +0 -0
  104. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/trace/__init__.py +0 -0
  105. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/trace/adjusting_exporter_test.py +0 -0
  106. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/trace/default_exporter_test.py +0 -0
  107. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/core/trace/realtime_processor_test.py +0 -0
  108. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/testing_test.py +0 -0
  109. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/veneer/reflection_server_test.py +0 -0
  110. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/veneer/server_test.py +0 -0
  111. {genkit-0.5.2 → genkit-0.6.0}/tests/genkit/veneer/veneer_resource_test.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: genkit
3
- Version: 0.5.2
3
+ Version: 0.6.0
4
4
  Summary: Genkit AI Framework
5
- Project-URL: Bug Tracker, https://github.com/firebase/genkit/issues
6
- Project-URL: Changelog, https://github.com/firebase/genkit/blob/main/py/packages/genkit/CHANGELOG.md
5
+ Project-URL: Bug Tracker, https://github.com/genkit-ai/genkit/issues
6
+ Project-URL: Changelog, https://github.com/genkit-ai/genkit/blob/main/py/packages/genkit/CHANGELOG.md
7
7
  Project-URL: Documentation, https://firebase.google.com/docs/genkit
8
- Project-URL: Homepage, https://github.com/firebase/genkit
9
- Project-URL: Repository, https://github.com/firebase/genkit/tree/main/py
8
+ Project-URL: Homepage, https://github.com/genkit-ai/genkit
9
+ Project-URL: Repository, https://github.com/genkit-ai/genkit/tree/main/py
10
10
  Author: Google
11
11
  License-Expression: Apache-2.0
12
12
  License-File: LICENSE
@@ -76,7 +76,7 @@ license = "Apache-2.0"
76
76
  name = "genkit"
77
77
  readme = "README.md"
78
78
  requires-python = ">=3.10"
79
- version = "0.5.2"
79
+ version = "0.6.0"
80
80
 
81
81
  [project.optional-dependencies]
82
82
  flask = ["genkit-plugin-flask"]
@@ -87,11 +87,11 @@ openai = ["genkit-plugin-compat-oai"]
87
87
  vertex-ai = ["genkit-plugin-vertex-ai"]
88
88
 
89
89
  [project.urls]
90
- "Bug Tracker" = "https://github.com/firebase/genkit/issues"
91
- "Changelog" = "https://github.com/firebase/genkit/blob/main/py/packages/genkit/CHANGELOG.md"
90
+ "Bug Tracker" = "https://github.com/genkit-ai/genkit/issues"
91
+ "Changelog" = "https://github.com/genkit-ai/genkit/blob/main/py/packages/genkit/CHANGELOG.md"
92
92
  "Documentation" = "https://firebase.google.com/docs/genkit"
93
- "Homepage" = "https://github.com/firebase/genkit"
94
- "Repository" = "https://github.com/firebase/genkit/tree/main/py"
93
+ "Homepage" = "https://github.com/genkit-ai/genkit"
94
+ "Repository" = "https://github.com/genkit-ai/genkit/tree/main/py"
95
95
 
96
96
  [build-system]
97
97
  build-backend = "hatchling.build"
@@ -21,9 +21,15 @@ from genkit._ai._prompt import (
21
21
  ExecutablePrompt,
22
22
  ModelStreamResponse,
23
23
  PromptGenerateOptions,
24
- ResumeOptions,
25
24
  )
26
- from genkit._ai._tools import ToolInterruptError, ToolRunContext, tool_response
25
+ from genkit._ai._tools import (
26
+ Interrupt,
27
+ Tool,
28
+ ToolRunContext,
29
+ respond_to_interrupt,
30
+ restart_tool,
31
+ tool,
32
+ )
27
33
  from genkit._core._action import Action, StreamResponse
28
34
  from genkit._core._error import GenkitError, PublicError
29
35
  from genkit._core._model import Document
@@ -93,7 +99,11 @@ __all__ = [
93
99
  # Errors
94
100
  'GenkitError',
95
101
  'PublicError',
96
- 'ToolInterruptError',
102
+ 'Interrupt',
103
+ 'Tool',
104
+ 'respond_to_interrupt',
105
+ 'restart_tool',
106
+ 'tool',
97
107
  # Content types
98
108
  'Constrained',
99
109
  'CustomPart',
@@ -126,9 +136,7 @@ __all__ = [
126
136
  'ActionRunContext',
127
137
  'ExecutablePrompt',
128
138
  'PromptGenerateOptions',
129
- 'ResumeOptions',
130
139
  'ToolRunContext',
131
- 'tool_response',
132
140
  'ModelRequest',
133
141
  'ModelResponse',
134
142
  'ModelResponseChunk',
@@ -21,18 +21,17 @@ from __future__ import annotations
21
21
  import asyncio
22
22
  import inspect
23
23
  import json
24
+ import os
24
25
  import signal
25
26
  import socket
26
27
  import threading
27
28
  import uuid
28
- from collections.abc import Awaitable, Callable, Coroutine
29
+ from collections.abc import Awaitable, Callable, Coroutine, Sequence
29
30
  from pathlib import Path
30
- from typing import Any, ParamSpec, TypeVar, cast, overload
31
+ from typing import Any, TypeVar, cast, overload
31
32
 
32
33
  import anyio
33
34
  import uvicorn
34
- from opentelemetry import trace as trace_api
35
- from opentelemetry.sdk.trace import TracerProvider
36
35
  from pydantic import BaseModel
37
36
 
38
37
  from genkit._ai._embedding import EmbedderFn, EmbedderOptions, EmbedderRef, define_embedder
@@ -45,7 +44,7 @@ from genkit._ai._evaluator import (
45
44
  )
46
45
  from genkit._ai._formats import built_in_formats
47
46
  from genkit._ai._formats._types import FormatDef
48
- from genkit._ai._generate import define_generate_action, generate_action
47
+ from genkit._ai._generate import define_generate_action, generate_action, registry_with_inline_tools
49
48
  from genkit._ai._model import (
50
49
  Message,
51
50
  ModelConfig,
@@ -71,7 +70,7 @@ from genkit._ai._resource import (
71
70
  ResourceOptions,
72
71
  define_resource,
73
72
  )
74
- from genkit._ai._tools import define_tool
73
+ from genkit._ai._tools import Tool, define_interrupt, define_tool
75
74
  from genkit._core._action import Action, ActionKind, ActionRunContext
76
75
  from genkit._core._background import (
77
76
  BackgroundAction,
@@ -94,8 +93,9 @@ from genkit._core._logger import get_logger
94
93
  from genkit._core._model import Document
95
94
  from genkit._core._plugin import Plugin
96
95
  from genkit._core._reflection import ReflectionServer, ServerSpec, create_reflection_asgi_app
96
+ from genkit._core._reflection_v2 import ReflectionServerV2
97
97
  from genkit._core._registry import Registry
98
- from genkit._core._tracing import run_in_new_span
98
+ from genkit._core._tracing import SpanMetadata, run_in_new_span
99
99
  from genkit._core._typing import (
100
100
  BaseDataPoint,
101
101
  Embedding,
@@ -105,8 +105,9 @@ from genkit._core._typing import (
105
105
  ModelInfo,
106
106
  Operation,
107
107
  Part,
108
- SpanMetadata,
109
108
  ToolChoice,
109
+ ToolRequestPart,
110
+ ToolResponsePart,
110
111
  )
111
112
 
112
113
  from ._decorators import _FlowDecorator, _FlowDecoratorWithChunk
@@ -118,7 +119,7 @@ logger = get_logger(__name__)
118
119
  InputT = TypeVar('InputT')
119
120
  OutputT = TypeVar('OutputT')
120
121
  ChunkT = TypeVar('ChunkT')
121
- P = ParamSpec('P')
122
+
122
123
  R = TypeVar('R')
123
124
  T = TypeVar('T')
124
125
 
@@ -260,16 +261,45 @@ class Genkit:
260
261
  metadata=metadata,
261
262
  )
262
263
 
263
- def tool(
264
- self, name: str | None = None, description: str | None = None
265
- ) -> Callable[[Callable[P, T]], Callable[P, T]]:
264
+ def tool(self, name: str | None = None, description: str | None = None) -> Callable[[Callable[..., Any]], Tool]:
266
265
  """Decorator to register a function as a tool."""
267
266
 
268
- def wrapper(func: Callable[P, T]) -> Callable[P, T]:
267
+ def wrapper(func: Callable[..., Any]) -> Tool:
269
268
  return define_tool(self.registry, func, name, description)
270
269
 
271
270
  return wrapper
272
271
 
272
+ def define_interrupt(
273
+ self,
274
+ name: str,
275
+ *,
276
+ input_schema: type[BaseModel] | dict[str, object] | None = None,
277
+ description: str | None = None,
278
+ ) -> Tool:
279
+ """Register an interrupt tool that always pauses for user input.
280
+
281
+ Args:
282
+ name: Tool name
283
+ input_schema: Optional input schema (Pydantic model or JSON schema dict)
284
+ description: Tool description
285
+
286
+ Returns:
287
+ The registered interrupt tool
288
+
289
+ Example:
290
+ ask_user = ai.define_interrupt(
291
+ name='ask_user',
292
+ input_schema=Question,
293
+ description='Ask the user a question',
294
+ )
295
+ """
296
+ return define_interrupt(
297
+ self.registry,
298
+ name,
299
+ description=description,
300
+ input_schema=input_schema,
301
+ )
302
+
273
303
  def define_evaluator(
274
304
  self,
275
305
  *,
@@ -393,7 +423,7 @@ class Genkit:
393
423
  max_turns: int | None = None,
394
424
  return_tool_requests: bool | None = None,
395
425
  metadata: dict[str, object] | None = None,
396
- tools: list[str] | None = None,
426
+ tools: Sequence[str | Tool] | None = None,
397
427
  tool_choice: ToolChoice | None = None,
398
428
  use: list[ModelMiddleware] | None = None,
399
429
  docs: list[Document] | None = None,
@@ -421,7 +451,7 @@ class Genkit:
421
451
  max_turns: int | None = None,
422
452
  return_tool_requests: bool | None = None,
423
453
  metadata: dict[str, object] | None = None,
424
- tools: list[str] | None = None,
454
+ tools: Sequence[str | Tool] | None = None,
425
455
  tool_choice: ToolChoice | None = None,
426
456
  use: list[ModelMiddleware] | None = None,
427
457
  docs: list[Document] | None = None,
@@ -449,7 +479,7 @@ class Genkit:
449
479
  max_turns: int | None = None,
450
480
  return_tool_requests: bool | None = None,
451
481
  metadata: dict[str, object] | None = None,
452
- tools: list[str] | None = None,
482
+ tools: Sequence[str | Tool] | None = None,
453
483
  tool_choice: ToolChoice | None = None,
454
484
  use: list[ModelMiddleware] | None = None,
455
485
  docs: list[Document] | None = None,
@@ -477,7 +507,7 @@ class Genkit:
477
507
  max_turns: int | None = None,
478
508
  return_tool_requests: bool | None = None,
479
509
  metadata: dict[str, object] | None = None,
480
- tools: list[str] | None = None,
510
+ tools: Sequence[str | Tool] | None = None,
481
511
  tool_choice: ToolChoice | None = None,
482
512
  use: list[ModelMiddleware] | None = None,
483
513
  docs: list[Document] | None = None,
@@ -503,7 +533,7 @@ class Genkit:
503
533
  max_turns: int | None = None,
504
534
  return_tool_requests: bool | None = None,
505
535
  metadata: dict[str, object] | None = None,
506
- tools: list[str] | None = None,
536
+ tools: Sequence[str | Tool] | None = None,
507
537
  tool_choice: ToolChoice | None = None,
508
538
  use: list[ModelMiddleware] | None = None,
509
539
  docs: list[Document] | None = None,
@@ -630,9 +660,22 @@ class Genkit:
630
660
  # -------------------------------------------------------------------------
631
661
 
632
662
  def _start_reflection_background(self) -> None:
633
- """Start the Dev UI reflection server in a background daemon thread."""
663
+ """Start the Dev UI reflection server in a background daemon thread.
664
+
665
+ If GENKIT_REFLECTION_V2_SERVER is set (the CLI launches the runtime in
666
+ v2 mode and provides a WebSocket URL), run the v2 JSON-RPC client.
667
+ Otherwise start the v1 HTTP server.
668
+ """
634
669
 
635
670
  async def _run_server() -> None:
671
+ v2_url = os.environ.get('GENKIT_REFLECTION_V2_SERVER')
672
+ if v2_url:
673
+ await logger.ainfo(f'Genkit Dev UI reflection v2 client connecting to {v2_url}')
674
+ server_v2 = ReflectionServerV2(self.registry, v2_url)
675
+ self._reflection_ready.set()
676
+ await server_v2.run_forever()
677
+ return
678
+
636
679
  sockets: list[socket.socket] | None = None
637
680
  spec = self._reflection_server_spec
638
681
  if spec is None:
@@ -668,9 +711,8 @@ class Genkit:
668
711
 
669
712
  def _initialize_registry(self, model: str | None, plugins: list[Plugin] | None) -> None:
670
713
  """Initialize the registry with default model and plugins."""
671
- self.registry.default_model = model
672
714
  if model:
673
- self.registry.register_value('defaultModel', model, model)
715
+ self.registry.register_value('defaultModel', 'defaultModel', model)
674
716
  for fmt in built_in_formats:
675
717
  self.define_format(fmt)
676
718
 
@@ -743,10 +785,12 @@ class Genkit:
743
785
  prompt: str | list[Part] | None = None,
744
786
  system: str | list[Part] | None = None,
745
787
  messages: list[Message] | None = None,
746
- tools: list[str] | None = None,
788
+ tools: Sequence[str | Tool] | None = None,
747
789
  return_tool_requests: bool | None = None,
748
790
  tool_choice: ToolChoice | None = None,
749
- tool_responses: list[Part] | None = None,
791
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
792
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
793
+ resume_metadata: dict[str, Any] | None = None,
750
794
  config: dict[str, object] | ModelConfig | None = None,
751
795
  max_turns: int | None = None,
752
796
  context: dict[str, object] | None = None,
@@ -768,10 +812,12 @@ class Genkit:
768
812
  prompt: str | list[Part] | None = None,
769
813
  system: str | list[Part] | None = None,
770
814
  messages: list[Message] | None = None,
771
- tools: list[str] | None = None,
815
+ tools: Sequence[str | Tool] | None = None,
772
816
  return_tool_requests: bool | None = None,
773
817
  tool_choice: ToolChoice | None = None,
774
- tool_responses: list[Part] | None = None,
818
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
819
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
820
+ resume_metadata: dict[str, Any] | None = None,
775
821
  config: dict[str, object] | ModelConfig | None = None,
776
822
  max_turns: int | None = None,
777
823
  context: dict[str, object] | None = None,
@@ -791,10 +837,12 @@ class Genkit:
791
837
  prompt: str | list[Part] | None = None,
792
838
  system: str | list[Part] | None = None,
793
839
  messages: list[Message] | None = None,
794
- tools: list[str] | None = None,
840
+ tools: Sequence[str | Tool] | None = None,
795
841
  return_tool_requests: bool | None = None,
796
842
  tool_choice: ToolChoice | None = None,
797
- tool_responses: list[Part] | None = None,
843
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
844
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
845
+ resume_metadata: dict[str, Any] | None = None,
798
846
  config: dict[str, object] | ModelConfig | None = None,
799
847
  max_turns: int | None = None,
800
848
  context: dict[str, object] | None = None,
@@ -806,30 +854,37 @@ class Genkit:
806
854
  use: list[ModelMiddleware] | None = None,
807
855
  docs: list[Document] | None = None,
808
856
  ) -> ModelResponse[Any]:
809
- """Generate text or structured data using a language model."""
857
+ """Generate text or structured data using a language model.
858
+
859
+ ``tools`` is typed as ``Sequence`` rather than ``list`` because ``Sequence``
860
+ is covariant: ``list[Tool]`` or ``list[str]`` are both assignable to
861
+ ``Sequence[str | Tool]``, but not to ``list[str | Tool]``.
862
+ """
863
+ prompt_config = PromptConfig(
864
+ model=model,
865
+ prompt=prompt,
866
+ system=system,
867
+ messages=messages,
868
+ tools=tools,
869
+ return_tool_requests=return_tool_requests,
870
+ tool_choice=tool_choice,
871
+ resume_respond=resume_respond,
872
+ resume_restart=resume_restart,
873
+ resume_metadata=resume_metadata,
874
+ config=config,
875
+ max_turns=max_turns,
876
+ output_format=output_format,
877
+ output_content_type=output_content_type,
878
+ output_instructions=output_instructions,
879
+ output_schema=output_schema,
880
+ output_constrained=output_constrained,
881
+ docs=docs,
882
+ )
883
+ registry = await registry_with_inline_tools(self.registry, prompt_config.tools)
884
+ gen_options = await to_generate_action_options(registry, prompt_config)
810
885
  return await generate_action(
811
- self.registry,
812
- await to_generate_action_options(
813
- self.registry,
814
- PromptConfig(
815
- model=model,
816
- prompt=prompt,
817
- system=system,
818
- messages=messages,
819
- tools=tools,
820
- return_tool_requests=return_tool_requests,
821
- tool_choice=tool_choice,
822
- tool_responses=tool_responses,
823
- config=config,
824
- max_turns=max_turns,
825
- output_format=output_format,
826
- output_content_type=output_content_type,
827
- output_instructions=output_instructions,
828
- output_schema=output_schema,
829
- output_constrained=output_constrained,
830
- docs=docs,
831
- ),
832
- ),
886
+ registry,
887
+ gen_options,
833
888
  middleware=use,
834
889
  context=context if context else ActionRunContext._current_context(), # pyright: ignore[reportPrivateUsage]
835
890
  )
@@ -843,9 +898,12 @@ class Genkit:
843
898
  prompt: str | list[Part] | None = None,
844
899
  system: str | list[Part] | None = None,
845
900
  messages: list[Message] | None = None,
846
- tools: list[str] | None = None,
901
+ tools: Sequence[str | Tool] | None = None,
847
902
  return_tool_requests: bool | None = None,
848
903
  tool_choice: ToolChoice | None = None,
904
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
905
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
906
+ resume_metadata: dict[str, Any] | None = None,
849
907
  config: dict[str, object] | ModelConfig | None = None,
850
908
  max_turns: int | None = None,
851
909
  context: dict[str, object] | None = None,
@@ -868,9 +926,12 @@ class Genkit:
868
926
  prompt: str | list[Part] | None = None,
869
927
  system: str | list[Part] | None = None,
870
928
  messages: list[Message] | None = None,
871
- tools: list[str] | None = None,
929
+ tools: Sequence[str | Tool] | None = None,
872
930
  return_tool_requests: bool | None = None,
873
931
  tool_choice: ToolChoice | None = None,
932
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
933
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
934
+ resume_metadata: dict[str, Any] | None = None,
874
935
  config: dict[str, object] | ModelConfig | None = None,
875
936
  max_turns: int | None = None,
876
937
  context: dict[str, object] | None = None,
@@ -891,9 +952,12 @@ class Genkit:
891
952
  prompt: str | list[Part] | None = None,
892
953
  system: str | list[Part] | None = None,
893
954
  messages: list[Message] | None = None,
894
- tools: list[str] | None = None,
955
+ tools: Sequence[str | Tool] | None = None,
895
956
  return_tool_requests: bool | None = None,
896
957
  tool_choice: ToolChoice | None = None,
958
+ resume_respond: ToolResponsePart | list[ToolResponsePart] | None = None,
959
+ resume_restart: ToolRequestPart | list[ToolRequestPart] | None = None,
960
+ resume_metadata: dict[str, Any] | None = None,
897
961
  config: dict[str, object] | ModelConfig | None = None,
898
962
  max_turns: int | None = None,
899
963
  context: dict[str, object] | None = None,
@@ -910,28 +974,31 @@ class Genkit:
910
974
  channel: Channel[ModelResponseChunk, ModelResponse[Any]] = Channel(timeout=timeout)
911
975
 
912
976
  async def _run_generate() -> ModelResponse[Any]:
977
+ prompt_config = PromptConfig(
978
+ model=model,
979
+ prompt=prompt,
980
+ system=system,
981
+ messages=messages,
982
+ tools=tools,
983
+ return_tool_requests=return_tool_requests,
984
+ tool_choice=tool_choice,
985
+ resume_respond=resume_respond,
986
+ resume_restart=resume_restart,
987
+ resume_metadata=resume_metadata,
988
+ config=config,
989
+ max_turns=max_turns,
990
+ output_format=output_format,
991
+ output_content_type=output_content_type,
992
+ output_instructions=output_instructions,
993
+ output_schema=output_schema,
994
+ output_constrained=output_constrained,
995
+ docs=docs,
996
+ )
997
+ registry = await registry_with_inline_tools(self.registry, prompt_config.tools)
998
+ gen_options = await to_generate_action_options(registry, prompt_config)
913
999
  return await generate_action(
914
- self.registry,
915
- await to_generate_action_options(
916
- self.registry,
917
- PromptConfig(
918
- model=model,
919
- prompt=prompt,
920
- system=system,
921
- messages=messages,
922
- tools=tools,
923
- return_tool_requests=return_tool_requests,
924
- tool_choice=tool_choice,
925
- config=config,
926
- max_turns=max_turns,
927
- output_format=output_format,
928
- output_content_type=output_content_type,
929
- output_instructions=output_instructions,
930
- output_schema=output_schema,
931
- output_constrained=output_constrained,
932
- docs=docs,
933
- ),
934
- ),
1000
+ registry,
1001
+ gen_options,
935
1002
  on_chunk=lambda c: channel.send(c),
936
1003
  middleware=use,
937
1004
  context=context if context else ActionRunContext._current_context(), # pyright: ignore[reportPrivateUsage]
@@ -1055,32 +1122,6 @@ class Genkit:
1055
1122
  """Get the current execution context, or None if not in an action."""
1056
1123
  return ActionRunContext._current_context() # pyright: ignore[reportPrivateUsage]
1057
1124
 
1058
- def dynamic_tool(
1059
- self,
1060
- *,
1061
- name: str,
1062
- fn: Callable[..., object],
1063
- description: str | None = None,
1064
- metadata: dict[str, object] | None = None,
1065
- ) -> Action:
1066
- """Create an unregistered tool action for passing directly to generate()."""
1067
- tool_meta: dict[str, object] = metadata.copy() if metadata else {}
1068
- tool_meta['type'] = 'tool'
1069
- tool_meta['dynamic'] = True
1070
- return Action(
1071
- kind=ActionKind.TOOL,
1072
- name=name,
1073
- fn=fn, # type: ignore[arg-type] # dynamic tools may be sync
1074
- description=description,
1075
- metadata=tool_meta,
1076
- )
1077
-
1078
- async def flush_tracing(self) -> None:
1079
- """Flush all pending trace spans to exporters."""
1080
- provider = trace_api.get_tracer_provider()
1081
- if isinstance(provider, TracerProvider):
1082
- await asyncio.to_thread(provider.force_flush)
1083
-
1084
1125
  async def run(
1085
1126
  self,
1086
1127
  *,
@@ -1092,8 +1133,8 @@ class Genkit:
1092
1133
  if not inspect.iscoroutinefunction(fn):
1093
1134
  raise TypeError('fn must be a coroutine function')
1094
1135
 
1095
- span_metadata = SpanMetadata(name=name, metadata=metadata)
1096
- with run_in_new_span(span_metadata, labels={'genkit:type': 'flowStep'}) as span:
1136
+ span_metadata = SpanMetadata(name=name, type='flowStep', metadata=metadata)
1137
+ with run_in_new_span(span_metadata) as span:
1097
1138
  try:
1098
1139
  result = await fn()
1099
1140
  output = (
@@ -1132,7 +1173,7 @@ class Genkit:
1132
1173
  prompt: str | list[Part] | None = None,
1133
1174
  system: str | list[Part] | None = None,
1134
1175
  messages: list[Message] | None = None,
1135
- tools: list[str] | None = None,
1176
+ tools: Sequence[str | Tool] | None = None,
1136
1177
  return_tool_requests: bool | None = None,
1137
1178
  tool_choice: ToolChoice | None = None,
1138
1179
  config: dict[str, object] | ModelConfig | None = None,
@@ -1148,7 +1189,7 @@ class Genkit:
1148
1189
  ) -> Operation:
1149
1190
  """Generate content using a long-running model, returning an Operation to poll."""
1150
1191
  # Resolve the model and check for long_running support
1151
- resolved_model = model or self.registry.default_model
1192
+ resolved_model = model or cast(str | None, self.registry.lookup_value('defaultModel', 'defaultModel'))
1152
1193
  if not resolved_model:
1153
1194
  raise GenkitError(
1154
1195
  status='INVALID_ARGUMENT',
@@ -23,11 +23,11 @@ from pydantic import BaseModel, ConfigDict
23
23
  from pydantic.alias_generators import to_camel
24
24
  from typing_extensions import Never
25
25
 
26
- from genkit._core._action import Action, ActionKind, ActionMetadata, get_func_description
26
+ from genkit._core._action import Action, ActionKind, get_func_description
27
27
  from genkit._core._model import Document
28
28
  from genkit._core._registry import Registry
29
29
  from genkit._core._schema import to_json_schema
30
- from genkit._core._typing import EmbedRequest, EmbedResponse
30
+ from genkit._core._typing import ActionMetadata, EmbedRequest, EmbedResponse
31
31
 
32
32
 
33
33
  class EmbedderSupports(BaseModel):
@@ -103,7 +103,7 @@ def embedder_action_metadata(
103
103
  embedder_info['customOptions'] = options.config_schema if options.config_schema else None
104
104
 
105
105
  return ActionMetadata(
106
- kind=ActionKind.EMBEDDER,
106
+ action_type=ActionKind.EMBEDDER,
107
107
  name=name,
108
108
  input_json_schema=to_json_schema(EmbedRequest),
109
109
  output_json_schema=to_json_schema(EmbedResponse),
@@ -25,19 +25,19 @@ from typing import Any, ClassVar, TypeVar, cast
25
25
  from pydantic import BaseModel, ConfigDict
26
26
  from pydantic.alias_generators import to_camel
27
27
 
28
- from genkit._core._action import Action, ActionKind, ActionMetadata
28
+ from genkit._core._action import Action, ActionKind
29
29
  from genkit._core._logger import get_logger
30
30
  from genkit._core._registry import Registry
31
31
  from genkit._core._schema import to_json_schema
32
- from genkit._core._tracing import run_in_new_span
32
+ from genkit._core._tracing import SpanMetadata, run_in_new_span
33
33
  from genkit._core._typing import (
34
+ ActionMetadata,
34
35
  BaseDataPoint,
35
36
  EvalFnResponse,
36
37
  EvalRequest,
37
38
  EvalResponse,
38
39
  EvalStatusEnum,
39
40
  Score,
40
- SpanMetadata,
41
41
  )
42
42
 
43
43
  logger = get_logger(__name__)
@@ -76,7 +76,7 @@ def evaluator_action_metadata(
76
76
  ) -> ActionMetadata:
77
77
  """Create ActionMetadata for an evaluator action."""
78
78
  return ActionMetadata(
79
- kind=ActionKind.EVALUATOR,
79
+ action_type=ActionKind.EVALUATOR,
80
80
  name=name,
81
81
  input_json_schema=to_json_schema(EvalRequest),
82
82
  output_json_schema=to_json_schema(list[EvalFnResponse]),
@@ -132,13 +132,15 @@ def define_evaluator(
132
132
  datapoint.test_case_id = str(uuid.uuid4())
133
133
  span_metadata = SpanMetadata(
134
134
  name=f'Test Case {datapoint.test_case_id}',
135
+ type='evaluator',
136
+ input=datapoint,
135
137
  metadata={'evaluator:evalRunId': req.eval_run_id},
136
138
  )
137
139
  try:
138
140
  # Try to run with tracing, but fallback if tracing infrastructure fails
139
141
  # (e.g., in environments with NonRecordingSpans like pre-commit)
140
142
  try:
141
- with run_in_new_span(span_metadata, labels={'genkit:type': 'evaluator'}) as span:
143
+ with run_in_new_span(span_metadata) as span:
142
144
  span_id = format(span.get_span_context().span_id, '016x')
143
145
  trace_id = format(span.get_span_context().trace_id, '032x')
144
146
  try: