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.
Files changed (47) hide show
  1. package/README.md +26 -26
  2. package/edgeone-bin/edgeone.js +3 -3
  3. package/edgeone-dist/cli.js +86890 -2307
  4. package/edgeone-dist/libs-pages-agent-toolkit/README.md +8 -0
  5. package/edgeone-dist/libs-pages-agent-toolkit/pages_agent_toolkit-0.1.40-py3-none-any.whl +0 -0
  6. package/edgeone-dist/libs-pages-blob-python/README.md +38 -0
  7. package/edgeone-dist/libs-pages-blob-python/pages_blob_python-0.12.0-py3-none-any.whl +0 -0
  8. package/edgeone-dist/pages/dev/runner-worker.js +86532 -2090
  9. package/edgeone-dist/pages/observability-python/__init__.py +32 -0
  10. package/edgeone-dist/pages/observability-python/_compat.py +69 -0
  11. package/edgeone-dist/pages/observability-python/apm/__init__.py +13 -0
  12. package/edgeone-dist/pages/observability-python/apm/config.py +85 -0
  13. package/edgeone-dist/pages/observability-python/apm/llm_semconv.py +53 -0
  14. package/edgeone-dist/pages/observability-python/apm/metrics_bridge.py +226 -0
  15. package/edgeone-dist/pages/observability-python/apm/span_exporter.py +384 -0
  16. package/edgeone-dist/pages/observability-python/bootstrap.py +158 -0
  17. package/edgeone-dist/pages/observability-python/build.py +119 -0
  18. package/edgeone-dist/pages/observability-python/context_patches.py +167 -0
  19. package/edgeone-dist/pages/observability-python/context_propagator.py +78 -0
  20. package/edgeone-dist/pages/observability-python/registry.json +95 -0
  21. package/edgeone-dist/pages/observability-python/registry.py +141 -0
  22. package/edgeone-dist/pages/observability-python/telemetry.py +214 -0
  23. package/edgeone-dist/pages/observability-python/tracer.py +165 -0
  24. package/edgeone-dist/pages/templates/agent-python/__init__.py +11 -0
  25. package/edgeone-dist/pages/templates/agent-python/adapter.py +908 -0
  26. package/edgeone-dist/pages/templates/agent-python/context.py +689 -0
  27. package/edgeone-dist/pages/templates/agent-python/local_blob_store.py +172 -0
  28. package/edgeone-dist/pages/templates/agent-python/memory.py +2301 -0
  29. package/edgeone-dist/pages/templates/agent-python/runtime.py +839 -0
  30. package/edgeone-dist/pages/templates/agent-python/store.py +204 -0
  31. package/edgeone-dist/studio/ui/assets/agent-obs-Dvi4IpEy.js +4 -0
  32. package/edgeone-dist/studio/ui/assets/agent-obs-qDJCE0TQ.css +1 -0
  33. package/edgeone-dist/studio/ui/assets/highlight-ClXAL37H.js +3 -0
  34. package/edgeone-dist/studio/ui/assets/index-Cz5oQnXW.css +1 -0
  35. package/edgeone-dist/studio/ui/assets/index-DD3d108t.js +1 -0
  36. package/edgeone-dist/studio/ui/assets/moment-BYRO94Ou.js +10 -0
  37. package/edgeone-dist/studio/ui/assets/react-dom-ZzBHVjtL.js +24 -0
  38. package/edgeone-dist/studio/ui/assets/react-hnpCyKql.js +17 -0
  39. package/edgeone-dist/studio/ui/assets/tea-CADagUwM.css +1 -0
  40. package/edgeone-dist/studio/ui/assets/tea-Slf_ajmf.js +334 -0
  41. package/edgeone-dist/studio/ui/favicon.ico +0 -0
  42. package/edgeone-dist/studio/ui/index.html +31 -0
  43. package/libs-pages-agent-toolkit/README.md +8 -0
  44. package/libs-pages-agent-toolkit/pages_agent_toolkit-0.1.40-py3-none-any.whl +0 -0
  45. package/libs-pages-blob-python/README.md +38 -0
  46. package/libs-pages-blob-python/pages_blob_python-0.12.0-py3-none-any.whl +0 -0
  47. 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
+ )