@agentsdock/server 1.0.11-beta.2 → 1.0.11
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/package.json +1 -1
- package/server/VERSION +1 -1
- package/server/agent_server.py +53 -5
- package/server/install.sh +17 -2
- package/server/interactive_chat_share_routes.py +1 -1
- package/server/interactive_chat_share_web.py +2 -2
- package/server/npm/agentsdock/QR-NOTICES.txt +56 -0
- package/server/npm/agentsdock/pair.cjs +123 -0
- package/server/npm/agentsdock/qr-renderer.cjs +15 -0
- package/server/public_chat_share_routes.py +8 -6
- package/server/public_chat_shares.py +17 -7
- package/server/shared_chat_analytics_web.py +5 -0
package/package.json
CHANGED
package/server/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.11
|
|
1
|
+
1.0.11
|
package/server/agent_server.py
CHANGED
|
@@ -32364,6 +32364,9 @@ SEMANTIC_TIMELINE_EVENT_BUDGET_PER_ITEM = 4
|
|
|
32364
32364
|
SEMANTIC_TIMELINE_ESSENTIAL_LIMIT_PER_ITEM = 32
|
|
32365
32365
|
SEMANTIC_TIMELINE_ESSENTIAL_PAGE_OVERFLOW_LIMIT = 128
|
|
32366
32366
|
SEMANTIC_TIMELINE_TRACE_ANCHOR_PAGE_OVERFLOW_LIMIT = 128
|
|
32367
|
+
# Same-ID history corrections clear previously cached replay bubbles. They
|
|
32368
|
+
# need their own bounded allowance, not the slots reserved for chat content.
|
|
32369
|
+
SEMANTIC_TIMELINE_REPAIR_PAGE_OVERFLOW_LIMIT = 256
|
|
32367
32370
|
JOB_RUN_HISTORY_TEXT_LIMIT = 64 * 1024
|
|
32368
32371
|
SEMANTIC_TIMELINE_ESSENTIAL_DETAIL_TYPES = {
|
|
32369
32372
|
"artifact_created",
|
|
@@ -35760,9 +35763,6 @@ def collect_semantic_timeline_events(
|
|
|
35760
35763
|
deduplicated[identity] = event
|
|
35761
35764
|
return True
|
|
35762
35765
|
|
|
35763
|
-
for event in page_repairs:
|
|
35764
|
-
append_with_limit(event, event_limit)
|
|
35765
|
-
|
|
35766
35766
|
# Every selected semantic item gets one representative before any item
|
|
35767
35767
|
# receives detail. The page-size clamp in read_semantic_timeline_page()
|
|
35768
35768
|
# guarantees that this baseline always fits.
|
|
@@ -35777,6 +35777,22 @@ def collect_semantic_timeline_events(
|
|
|
35777
35777
|
for event in secondary:
|
|
35778
35778
|
append_with_limit(event, event_limit)
|
|
35779
35779
|
|
|
35780
|
+
# Reserve both sides of ordinary turns before emitting repair receipts.
|
|
35781
|
+
# A single imported run can contain hundreds of corrected boundaries:
|
|
35782
|
+
# charging them to the ordinary budget used to leave only trace anchors
|
|
35783
|
+
# for recent turns. Extend that budget only by receipts actually added,
|
|
35784
|
+
# retaining its remaining detail capacity and the absolute response cap.
|
|
35785
|
+
repair_allowance = min(
|
|
35786
|
+
SEMANTIC_TIMELINE_REPAIR_PAGE_OVERFLOW_LIMIT,
|
|
35787
|
+
MAX_EVENT_RESPONSE_LIMIT - event_limit,
|
|
35788
|
+
)
|
|
35789
|
+
repair_limit = len(deduplicated) + repair_allowance
|
|
35790
|
+
repair_count = 0
|
|
35791
|
+
for event in page_repairs:
|
|
35792
|
+
if append_with_limit(event, repair_limit):
|
|
35793
|
+
repair_count += 1
|
|
35794
|
+
event_limit += repair_count
|
|
35795
|
+
|
|
35780
35796
|
# Files and reviewable diffs are semantic output, not optional trace
|
|
35781
35797
|
# detail. Give each selected item a generous but bounded overflow and also
|
|
35782
35798
|
# cap total page overflow. This preserves normal multi-video workflows
|
|
@@ -50729,6 +50745,10 @@ def public_session(sess: dict[str, Any], *, summary: bool = False) -> dict[str,
|
|
|
50729
50745
|
if sess.get("title") == "New chat" and not public["backend_locked"]:
|
|
50730
50746
|
public["empty_chat_cleanup"] = "client-v1"
|
|
50731
50747
|
public["codex_provider"] = codex_provider.session_choice(sess.get("codex_provider"))
|
|
50748
|
+
if summary and "codex_goal" in sess:
|
|
50749
|
+
goal = sess.get("codex_goal")
|
|
50750
|
+
public["codex_goal_status"] = goal.get("status") if isinstance(goal, dict) else None
|
|
50751
|
+
public["codex_goal_updated_at"] = goal.get("updatedAt") if isinstance(goal, dict) else None
|
|
50732
50752
|
connection = sess.get("provider_connection") or "default"
|
|
50733
50753
|
# Keep legacy native summaries sparse, but retain a stored default as the
|
|
50734
50754
|
# tombstone that clears a previously selected custom API in client caches.
|
|
@@ -81506,6 +81526,22 @@ async def codex_provider_mcp(request: Request) -> Response:
|
|
|
81506
81526
|
})
|
|
81507
81527
|
|
|
81508
81528
|
|
|
81529
|
+
@app.get("/api/connection-addresses")
|
|
81530
|
+
async def connection_addresses(request: Request) -> dict[str, Any]:
|
|
81531
|
+
require_native_admin_control(request)
|
|
81532
|
+
# Discover only on explicit QR sharing, never on the frequently polled health path.
|
|
81533
|
+
from server_instances import candidate_addresses, connection_choices, tailscale_status
|
|
81534
|
+
|
|
81535
|
+
def discover() -> list[str]:
|
|
81536
|
+
choices = connection_choices(
|
|
81537
|
+
SERVER_BIND_ADDRESS, SERVER_PORT,
|
|
81538
|
+
candidate_addresses(SERVER_BIND_ADDRESS, SERVER_PORT), tailscale_status(),
|
|
81539
|
+
)
|
|
81540
|
+
return list(dict.fromkeys(filter(None, [choices["tailscale"], *choices["lan"]])))[:6]
|
|
81541
|
+
|
|
81542
|
+
return {"version": 1, "server_identity": server_identity(), "urls": await asyncio.to_thread(discover)}
|
|
81543
|
+
|
|
81544
|
+
|
|
81509
81545
|
@app.get("/api/health")
|
|
81510
81546
|
async def health() -> dict[str, Any]:
|
|
81511
81547
|
await reconcile_idle_queued_turns_from_health_poll()
|
|
@@ -91026,7 +91062,15 @@ def claude_completed_fork_boundary(
|
|
|
91026
91062
|
# final projected message can identify the inclusive native cutoff.
|
|
91027
91063
|
expected_text = projected_text if projected_text and final_text.endswith(projected_text) else final_text
|
|
91028
91064
|
recorded_uuid = str(final_projection.get("provider_message_id") or "") if expected_text == projected_text else ""
|
|
91029
|
-
|
|
91065
|
+
cutoff_ts = str(terminal.get("ts") or "")
|
|
91066
|
+
cutoff_time = parse_job_timestamp(cutoff_ts)
|
|
91067
|
+
# now_iso() truncates server events to whole seconds; native Claude
|
|
91068
|
+
# records retain milliseconds. Only an exact completed-message UUID can
|
|
91069
|
+
# disambiguate another turn in that same second. Keep legacy text-only
|
|
91070
|
+
# matching and explicitly fractional timestamps on the strict cutoff.
|
|
91071
|
+
cutoff_second_is_truncated = bool(recorded_uuid and re.fullmatch(
|
|
91072
|
+
r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", cutoff_ts,
|
|
91073
|
+
))
|
|
91030
91074
|
started = next((
|
|
91031
91075
|
event for event in reversed(events[:-1])
|
|
91032
91076
|
if event.get("type") == "turn_started" and str(event.get("run_id") or "") == run_id
|
|
@@ -91047,7 +91091,11 @@ def claude_completed_fork_boundary(
|
|
|
91047
91091
|
if not record_uuid or (recorded_uuid and record_uuid != recorded_uuid):
|
|
91048
91092
|
continue
|
|
91049
91093
|
record_time = parse_job_timestamp(str(record.get("timestamp") or ""))
|
|
91050
|
-
if cutoff_time is None or record_time is None
|
|
91094
|
+
if cutoff_time is None or record_time is None:
|
|
91095
|
+
continue
|
|
91096
|
+
if record_time > cutoff_time and not (
|
|
91097
|
+
cutoff_second_is_truncated and record_time < cutoff_time + 1
|
|
91098
|
+
):
|
|
91051
91099
|
continue
|
|
91052
91100
|
if not recorded_uuid and (start_time is None or record_time < start_time):
|
|
91053
91101
|
continue
|
package/server/install.sh
CHANGED
|
@@ -1387,6 +1387,13 @@ print_token_for_copy() {
|
|
|
1387
1387
|
local copy_reply=""
|
|
1388
1388
|
local clipboard_command=()
|
|
1389
1389
|
printf '\nAccess token (%s):\n%s\n\n' "$INSTANCE_NAME" "$access_token"
|
|
1390
|
+
# Render locally, only in an interactive terminal. No credentials in argv.
|
|
1391
|
+
local pairing_script="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/npm/agentsdock/pair.cjs"
|
|
1392
|
+
if [[ -f "$pairing_script" ]] && command -v node >/dev/null 2>&1; then
|
|
1393
|
+
node "$pairing_script" "$INSTANCE_NAME" || true
|
|
1394
|
+
else
|
|
1395
|
+
printf 'Show a connection QR with: agentsdock pair %s\n' "$INSTANCE_NAME"
|
|
1396
|
+
fi
|
|
1390
1397
|
# A remote clipboard is not the user's local clipboard. Do not emit OSC 52
|
|
1391
1398
|
# sequences or attempt to modify a remote desktop's clipboard over SSH.
|
|
1392
1399
|
if [[ -n "${SSH_CONNECTION:-}${SSH_CLIENT:-}${SSH_TTY:-}" ]]; then
|
|
@@ -1839,7 +1846,7 @@ if [[ "$TEAM_HUB_MODE" == "host" && "$TEAM_HUB_OPERATION_PENDING" != "true" \
|
|
|
1839
1846
|
fi
|
|
1840
1847
|
fi
|
|
1841
1848
|
|
|
1842
|
-
RELEASE_FILES=(activation_transaction.py execution_activation.py execution_legacy_runner.py execution_preparation.py update_preparation.py update_handoff.py update_recovery.py execution_update_status.py execution_uninstall.py execution_recovery.py execution_recovery_status.py execution_http.py execution_durability.py execution_control.py execution_install.py execution_maintenance.py execution_manage.py execution_ownership.py execution_service.py execution_transport.py agent_server.py local_session_ownership.py cursor_history.py workspace_git.py team_hub_host.py secure_peer_runtime.py team_mail_runtime.py team_mail_websocket.py team_mail_grants.py secure_peer_delivery.py agentsdock_jobs.py agentsdock_chats.py chat_mailbox.py agentsdock_emergency.py agentsdock_publish.py agentsdock_mail.py agentsdock_team.py provider_commands.py provider_usage.py claude_sdk_client.py claude_model_catalog.py claude_goals.py claude_background_reconciliation.py codex_app_server.py codex_auth.py codex_provider.py codex_response_stream.py provider_connections.py cursor_api_key.py side_questions.py title_generation.py codex_side_question.py codex_side_chat_progress.py claude_side_question.py cursor_agent_client.py cursor_provider_mcp.py opencode_agent_client.py gemini_acp_client.py gemini_history.py gemini_content.py gemini_import.py gemini_runtime.py gemini_runner.py gemini_permissions.py gemini_api.py cursor_process_guard.py transcript_reader.py claude_history_repair.py claude_history_provenance.py codex_history_repair.py public_chat_shares.py public_chat_transcript.py public_chat_share_routes.py interactive_chat_shares.py interactive_chat_share_routes.py interactive_chat_share_web.py interactive_chat_projection.py interactive_chat_runtime.py interactive_chat_native.py shared_chat_videos.py shared_chat_video_stream.py interactive_chat_controls.py install.sh uninstall.sh instances.sh server_instances.py update_runner.py pyproject.toml uv.lock VERSION release-public-key.pem LICENSE NOTICE)
|
|
1849
|
+
RELEASE_FILES=(activation_transaction.py execution_activation.py execution_legacy_runner.py execution_preparation.py update_preparation.py update_handoff.py update_recovery.py execution_update_status.py execution_uninstall.py execution_recovery.py execution_recovery_status.py execution_http.py execution_durability.py execution_control.py execution_install.py execution_maintenance.py execution_manage.py execution_ownership.py execution_service.py execution_transport.py agent_server.py local_session_ownership.py cursor_history.py workspace_git.py team_hub_host.py secure_peer_runtime.py team_mail_runtime.py team_mail_websocket.py team_mail_grants.py secure_peer_delivery.py agentsdock_jobs.py agentsdock_chats.py chat_mailbox.py agentsdock_emergency.py agentsdock_publish.py agentsdock_mail.py agentsdock_team.py provider_commands.py provider_usage.py claude_sdk_client.py claude_model_catalog.py claude_goals.py claude_background_reconciliation.py codex_app_server.py codex_auth.py codex_provider.py codex_response_stream.py provider_connections.py cursor_api_key.py side_questions.py title_generation.py codex_side_question.py codex_side_chat_progress.py claude_side_question.py cursor_agent_client.py cursor_provider_mcp.py opencode_agent_client.py gemini_acp_client.py gemini_history.py gemini_content.py gemini_import.py gemini_runtime.py gemini_runner.py gemini_permissions.py gemini_api.py cursor_process_guard.py transcript_reader.py claude_history_repair.py claude_history_provenance.py codex_history_repair.py public_chat_shares.py public_chat_transcript.py public_chat_share_routes.py interactive_chat_shares.py interactive_chat_share_routes.py interactive_chat_share_web.py interactive_chat_projection.py interactive_chat_runtime.py interactive_chat_native.py shared_chat_videos.py shared_chat_analytics_web.py shared_chat_video_stream.py interactive_chat_controls.py install.sh uninstall.sh instances.sh server_instances.py npm/agentsdock/pair.cjs npm/agentsdock/qr-renderer.cjs npm/agentsdock/QR-NOTICES.txt update_runner.py pyproject.toml uv.lock VERSION release-public-key.pem LICENSE NOTICE)
|
|
1843
1850
|
RELEASE_DIRECTORIES=(agentsdock_team_hub)
|
|
1844
1851
|
TEAM_HUB_RELEASE_FILES=(
|
|
1845
1852
|
__init__.py
|
|
@@ -1880,6 +1887,12 @@ TEAM_HUB_RELEASE_FILES=(
|
|
|
1880
1887
|
migrations/0023_team_message_search.sql
|
|
1881
1888
|
)
|
|
1882
1889
|
|
|
1890
|
+
for directory in npm npm/agentsdock; do
|
|
1891
|
+
if [[ ! -d "$SOURCE_DIR/$directory" || -L "$SOURCE_DIR/$directory" ]]; then
|
|
1892
|
+
echo "$directory is missing beside install.sh or is not a real directory." >&2
|
|
1893
|
+
exit 1
|
|
1894
|
+
fi
|
|
1895
|
+
done
|
|
1883
1896
|
for name in "${RELEASE_FILES[@]}"; do
|
|
1884
1897
|
if [[ ! -f "$SOURCE_DIR/$name" || -L "$SOURCE_DIR/$name" ]]; then
|
|
1885
1898
|
echo "$name is missing beside install.sh or is not a regular release file." >&2
|
|
@@ -3785,12 +3798,13 @@ validate_staged_release_runtime() (
|
|
|
3785
3798
|
"$STAGE_DIR/interactive_chat_runtime.py" \
|
|
3786
3799
|
"$STAGE_DIR/interactive_chat_native.py" \
|
|
3787
3800
|
"$STAGE_DIR/shared_chat_videos.py" \
|
|
3801
|
+
"$STAGE_DIR/shared_chat_analytics_web.py" \
|
|
3788
3802
|
"$STAGE_DIR/shared_chat_video_stream.py" \
|
|
3789
3803
|
"$STAGE_DIR/interactive_chat_controls.py" \
|
|
3790
3804
|
"$STAGE_DIR/update_runner.py"
|
|
3791
3805
|
"$STAGE_DIR/.venv/bin/python" -m py_compile "$STAGE_DIR/server_instances.py"
|
|
3792
3806
|
"$STAGE_DIR/.venv/bin/python" -m compileall -q "$STAGE_DIR/agentsdock_team_hub"
|
|
3793
|
-
PYTHONPATH="$STAGE_DIR" "$STAGE_DIR/.venv/bin/python" -c 'import execution_activation, execution_preparation, update_preparation, update_handoff, update_recovery, execution_update_status, execution_uninstall, execution_recovery, execution_recovery_status, execution_http, execution_durability, execution_control, execution_install, execution_maintenance, execution_manage, execution_ownership, execution_service, execution_transport; import workspace_git, claude_model_catalog, server_instances, local_session_ownership, cursor_history; import codex_auth, codex_provider, codex_response_stream, provider_connections, cursor_api_key, side_questions, title_generation, codex_side_question, codex_side_chat_progress, claude_side_question, agentsdock_team_hub, cursor_agent_client, cursor_provider_mcp, opencode_agent_client, gemini_acp_client, gemini_history, gemini_content, gemini_import, gemini_runtime, gemini_runner, gemini_permissions, gemini_api, cursor_process_guard, secure_peer_delivery, secure_peer_runtime, team_mail_runtime, team_mail_websocket, team_mail_grants, team_hub_host, agentsdock_mail, agentsdock_team, transcript_reader, claude_history_repair, claude_history_provenance, claude_goals, claude_background_reconciliation, codex_history_repair, public_chat_shares, public_chat_transcript, public_chat_share_routes, interactive_chat_shares, interactive_chat_share_routes, interactive_chat_share_web, interactive_chat_projection, interactive_chat_runtime, interactive_chat_native, shared_chat_videos, shared_chat_video_stream, interactive_chat_controls, chat_mailbox, provider_commands, provider_usage; from agentsdock_team_hub import secure_peer, secure_peer_hub' >/dev/null
|
|
3807
|
+
PYTHONPATH="$STAGE_DIR" "$STAGE_DIR/.venv/bin/python" -c 'import execution_activation, execution_preparation, update_preparation, update_handoff, update_recovery, execution_update_status, execution_uninstall, execution_recovery, execution_recovery_status, execution_http, execution_durability, execution_control, execution_install, execution_maintenance, execution_manage, execution_ownership, execution_service, execution_transport; import workspace_git, claude_model_catalog, server_instances, local_session_ownership, cursor_history; import codex_auth, codex_provider, codex_response_stream, provider_connections, cursor_api_key, side_questions, title_generation, codex_side_question, codex_side_chat_progress, claude_side_question, agentsdock_team_hub, cursor_agent_client, cursor_provider_mcp, opencode_agent_client, gemini_acp_client, gemini_history, gemini_content, gemini_import, gemini_runtime, gemini_runner, gemini_permissions, gemini_api, cursor_process_guard, secure_peer_delivery, secure_peer_runtime, team_mail_runtime, team_mail_websocket, team_mail_grants, team_hub_host, agentsdock_mail, agentsdock_team, transcript_reader, claude_history_repair, claude_history_provenance, claude_goals, claude_background_reconciliation, codex_history_repair, public_chat_shares, public_chat_transcript, public_chat_share_routes, interactive_chat_shares, interactive_chat_share_routes, interactive_chat_share_web, interactive_chat_projection, interactive_chat_runtime, interactive_chat_native, shared_chat_videos, shared_chat_analytics_web, shared_chat_video_stream, interactive_chat_controls, chat_mailbox, provider_commands, provider_usage; from agentsdock_team_hub import secure_peer, secure_peer_hub' >/dev/null
|
|
3794
3808
|
)
|
|
3795
3809
|
|
|
3796
3810
|
abort_unclaimed_team_hub_reactivation() {
|
|
@@ -4108,6 +4122,7 @@ if [[ "$stage_identity" != *$'\n'* \
|
|
|
4108
4122
|
exit 1
|
|
4109
4123
|
fi
|
|
4110
4124
|
for name in "${RELEASE_FILES[@]}"; do
|
|
4125
|
+
mkdir -p "$(dirname -- "$STAGE_DIR/$name")"
|
|
4111
4126
|
install -m 644 "$SOURCE_DIR/$name" "$STAGE_DIR/$name"
|
|
4112
4127
|
done
|
|
4113
4128
|
mkdir -p "$STAGE_DIR/agentsdock_team_hub/migrations"
|
|
@@ -47,7 +47,7 @@ HTTP_COOKIE = "AgentsDock-Chat"
|
|
|
47
47
|
HEADERS = {
|
|
48
48
|
"Cache-Control": "no-store", "Referrer-Policy": "no-referrer", "X-Content-Type-Options": "nosniff",
|
|
49
49
|
"X-Robots-Tag": "noindex, nofollow, noarchive", "Cross-Origin-Resource-Policy": "same-origin",
|
|
50
|
-
"Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'",
|
|
50
|
+
"Content-Security-Policy": "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://api.mixpanel.com; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'",
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
|