edgeone 1.5.9 → 1.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 +26 -26
- package/edgeone-bin/edgeone.js +3 -3
- package/edgeone-dist/cli.js +86890 -2307
- package/edgeone-dist/libs-pages-agent-toolkit/README.md +8 -0
- package/edgeone-dist/libs-pages-agent-toolkit/pages_agent_toolkit-0.1.40-py3-none-any.whl +0 -0
- package/edgeone-dist/libs-pages-blob-python/README.md +38 -0
- package/edgeone-dist/libs-pages-blob-python/pages_blob_python-0.12.0-py3-none-any.whl +0 -0
- package/edgeone-dist/pages/dev/runner-worker.js +86532 -2090
- package/edgeone-dist/pages/observability-python/__init__.py +32 -0
- package/edgeone-dist/pages/observability-python/_compat.py +69 -0
- package/edgeone-dist/pages/observability-python/apm/__init__.py +13 -0
- package/edgeone-dist/pages/observability-python/apm/config.py +85 -0
- package/edgeone-dist/pages/observability-python/apm/llm_semconv.py +53 -0
- package/edgeone-dist/pages/observability-python/apm/metrics_bridge.py +226 -0
- package/edgeone-dist/pages/observability-python/apm/span_exporter.py +384 -0
- package/edgeone-dist/pages/observability-python/bootstrap.py +158 -0
- package/edgeone-dist/pages/observability-python/build.py +119 -0
- package/edgeone-dist/pages/observability-python/context_patches.py +167 -0
- package/edgeone-dist/pages/observability-python/context_propagator.py +78 -0
- package/edgeone-dist/pages/observability-python/registry.json +95 -0
- package/edgeone-dist/pages/observability-python/registry.py +141 -0
- package/edgeone-dist/pages/observability-python/telemetry.py +214 -0
- package/edgeone-dist/pages/observability-python/tracer.py +165 -0
- package/edgeone-dist/pages/templates/agent-python/__init__.py +11 -0
- package/edgeone-dist/pages/templates/agent-python/adapter.py +908 -0
- package/edgeone-dist/pages/templates/agent-python/context.py +689 -0
- package/edgeone-dist/pages/templates/agent-python/local_blob_store.py +172 -0
- package/edgeone-dist/pages/templates/agent-python/memory.py +2301 -0
- package/edgeone-dist/pages/templates/agent-python/runtime.py +839 -0
- package/edgeone-dist/pages/templates/agent-python/store.py +204 -0
- package/edgeone-dist/studio/ui/assets/agent-obs-Dvi4IpEy.js +4 -0
- package/edgeone-dist/studio/ui/assets/agent-obs-qDJCE0TQ.css +1 -0
- package/edgeone-dist/studio/ui/assets/highlight-ClXAL37H.js +3 -0
- package/edgeone-dist/studio/ui/assets/index-Cz5oQnXW.css +1 -0
- package/edgeone-dist/studio/ui/assets/index-DD3d108t.js +1 -0
- package/edgeone-dist/studio/ui/assets/moment-BYRO94Ou.js +10 -0
- package/edgeone-dist/studio/ui/assets/react-dom-ZzBHVjtL.js +24 -0
- package/edgeone-dist/studio/ui/assets/react-hnpCyKql.js +17 -0
- package/edgeone-dist/studio/ui/assets/tea-CADagUwM.css +1 -0
- package/edgeone-dist/studio/ui/assets/tea-Slf_ajmf.js +334 -0
- package/edgeone-dist/studio/ui/favicon.ico +0 -0
- package/edgeone-dist/studio/ui/index.html +31 -0
- package/libs-pages-agent-toolkit/README.md +8 -0
- package/libs-pages-agent-toolkit/pages_agent_toolkit-0.1.40-py3-none-any.whl +0 -0
- package/libs-pages-blob-python/README.md +38 -0
- package/libs-pages-blob-python/pages_blob_python-0.12.0-py3-none-any.whl +0 -0
- package/package.json +33 -7
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""User-facing tracer API for context.tracer."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
from typing import Any, Awaitable, Callable, TypeVar
|
|
6
|
+
|
|
7
|
+
from opentelemetry import context as otel_context
|
|
8
|
+
from opentelemetry import trace as otel_trace
|
|
9
|
+
from opentelemetry.trace import Span, StatusCode
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T")
|
|
12
|
+
|
|
13
|
+
# LangGraph 通过抛出这些异常实现 graph 暂停 / 控制流跳转,不属于业务错误。
|
|
14
|
+
# 命中后 user-tracer / exporter 都会把 span 状态从 ERROR 归一回 UNSET,
|
|
15
|
+
# 避免在 APM/langfuse 上误报。GeneratorExit / CancelledError 是 interrupt 触发
|
|
16
|
+
# 后流被拆除 / 取消时的 teardown 信号,同样不是业务错误,一并纳入。
|
|
17
|
+
_INTERRUPT_EXCEPTION_NAMES = frozenset({
|
|
18
|
+
"GraphInterrupt",
|
|
19
|
+
"NodeInterrupt",
|
|
20
|
+
"ParentCommand",
|
|
21
|
+
"GeneratorExit",
|
|
22
|
+
"CancelledError",
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _is_interrupt_exception(err: BaseException) -> bool:
|
|
27
|
+
"""Match LangGraph control-flow exceptions by class hierarchy name.
|
|
28
|
+
|
|
29
|
+
Walk the MRO so subclasses of GraphInterrupt etc. are also recognized,
|
|
30
|
+
while keeping it strict enough to avoid catching arbitrary user errors
|
|
31
|
+
that merely contain the substring "interrupt".
|
|
32
|
+
"""
|
|
33
|
+
for cls in type(err).__mro__:
|
|
34
|
+
if cls.__name__ in _INTERRUPT_EXCEPTION_NAMES:
|
|
35
|
+
return True
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TracerSpan:
|
|
40
|
+
"""Wrapper around an OTel Span with a simplified API."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, span: Span) -> None:
|
|
43
|
+
self._span = span
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def span_id(self) -> str:
|
|
47
|
+
return format(self._span.get_span_context().span_id, "016x")
|
|
48
|
+
|
|
49
|
+
def set_attribute(self, key: str, value: Any) -> None:
|
|
50
|
+
self._span.set_attribute(key, value)
|
|
51
|
+
|
|
52
|
+
def set_attributes(self, attributes: dict[str, Any]) -> None:
|
|
53
|
+
self._span.set_attributes(attributes)
|
|
54
|
+
|
|
55
|
+
def event(self, name: str, attributes: dict[str, Any] | None = None) -> None:
|
|
56
|
+
self._span.add_event(name, attributes=attributes)
|
|
57
|
+
|
|
58
|
+
def end(self) -> None:
|
|
59
|
+
self._span.end()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class AgentTracer:
|
|
63
|
+
"""User-facing tracer, set on ctx.tracer."""
|
|
64
|
+
|
|
65
|
+
def __init__(self, tracer_provider=None) -> None:
|
|
66
|
+
provider = tracer_provider or otel_trace.get_tracer_provider()
|
|
67
|
+
self._tracer = provider.get_tracer("edgeone-agent-user", "0.1.0")
|
|
68
|
+
|
|
69
|
+
def start_span(
|
|
70
|
+
self, name: str, attributes: dict[str, Any] | None = None
|
|
71
|
+
) -> TracerSpan:
|
|
72
|
+
parent_ctx = otel_context.get_current()
|
|
73
|
+
span = self._tracer.start_span(name, attributes=attributes or {}, context=parent_ctx)
|
|
74
|
+
return TracerSpan(span)
|
|
75
|
+
|
|
76
|
+
async def span(
|
|
77
|
+
self,
|
|
78
|
+
name: str,
|
|
79
|
+
fn: Callable[[TracerSpan], Awaitable[T] | T],
|
|
80
|
+
attributes: dict[str, Any] | None = None,
|
|
81
|
+
) -> T:
|
|
82
|
+
parent_ctx = otel_context.get_current()
|
|
83
|
+
span = self._tracer.start_span(name, attributes=attributes or {}, context=parent_ctx)
|
|
84
|
+
span_ctx = otel_trace.set_span_in_context(span, parent_ctx)
|
|
85
|
+
token = otel_context.attach(span_ctx)
|
|
86
|
+
try:
|
|
87
|
+
result = fn(TracerSpan(span))
|
|
88
|
+
if asyncio.iscoroutine(result):
|
|
89
|
+
result = await result
|
|
90
|
+
span.end()
|
|
91
|
+
return result # type: ignore[return-value]
|
|
92
|
+
except BaseException as err:
|
|
93
|
+
# LangGraph 的 interrupt() / Command 跳转通过抛异常实现,属于正常控制流,
|
|
94
|
+
# 不应记为 ERROR;但仍打标 agent.interrupt=true 方便平台筛选。
|
|
95
|
+
if _is_interrupt_exception(err):
|
|
96
|
+
try:
|
|
97
|
+
span.set_attribute("agent.interrupt", True)
|
|
98
|
+
span.set_attribute("agent.interrupt.type", type(err).__name__)
|
|
99
|
+
except Exception:
|
|
100
|
+
pass
|
|
101
|
+
else:
|
|
102
|
+
span.record_exception(err)
|
|
103
|
+
span.set_status(StatusCode.ERROR, str(err))
|
|
104
|
+
span.end()
|
|
105
|
+
raise
|
|
106
|
+
finally:
|
|
107
|
+
otel_context.detach(token)
|
|
108
|
+
|
|
109
|
+
def event(self, name: str, attributes: dict[str, Any] | None = None) -> None:
|
|
110
|
+
active_span = otel_trace.get_current_span()
|
|
111
|
+
if active_span:
|
|
112
|
+
active_span.add_event(name, attributes=attributes)
|
|
113
|
+
|
|
114
|
+
def set_attributes(self, attributes: dict[str, Any]) -> None:
|
|
115
|
+
active_span = otel_trace.get_current_span()
|
|
116
|
+
if active_span:
|
|
117
|
+
active_span.set_attributes(attributes)
|
|
118
|
+
|
|
119
|
+
def record_exception(
|
|
120
|
+
self, error: Exception, attributes: dict[str, Any] | None = None
|
|
121
|
+
) -> None:
|
|
122
|
+
active_span = otel_trace.get_current_span()
|
|
123
|
+
if active_span:
|
|
124
|
+
active_span.record_exception(error)
|
|
125
|
+
active_span.set_status(StatusCode.ERROR, str(error))
|
|
126
|
+
if attributes:
|
|
127
|
+
active_span.set_attributes(attributes)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class NoOpTracerSpan:
|
|
131
|
+
@property
|
|
132
|
+
def span_id(self) -> str:
|
|
133
|
+
return "0" * 16
|
|
134
|
+
|
|
135
|
+
def set_attribute(self, key: str, value: Any) -> None:
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def set_attributes(self, attributes: dict[str, Any]) -> None:
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
def event(self, name: str, attributes: dict[str, Any] | None = None) -> None:
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
def end(self) -> None:
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class NoOpTracer:
|
|
149
|
+
def start_span(self, name: str, attributes: dict[str, Any] | None = None) -> NoOpTracerSpan:
|
|
150
|
+
return NoOpTracerSpan()
|
|
151
|
+
|
|
152
|
+
async def span(self, name: str, fn: Callable, attributes: dict[str, Any] | None = None):
|
|
153
|
+
result = fn(NoOpTracerSpan())
|
|
154
|
+
if asyncio.iscoroutine(result):
|
|
155
|
+
return await result
|
|
156
|
+
return result
|
|
157
|
+
|
|
158
|
+
def event(self, name: str, attributes: dict[str, Any] | None = None) -> None:
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
def set_attributes(self, attributes: dict[str, Any]) -> None:
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
def record_exception(self, error: Exception, attributes: dict[str, Any] | None = None) -> None:
|
|
165
|
+
pass
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# src/pages/builder/templates/agent-python/__init__.py
|
|
2
|
+
from .memory import ( # noqa: F401
|
|
3
|
+
ConversationMemory,
|
|
4
|
+
Message,
|
|
5
|
+
ConversationMeta,
|
|
6
|
+
MemoryError,
|
|
7
|
+
MemoryValidationError,
|
|
8
|
+
MemoryNotFoundError,
|
|
9
|
+
MemoryQuotaExceededError,
|
|
10
|
+
MemoryStorageError,
|
|
11
|
+
)
|