Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions scripts/a2a/debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,22 @@ def build_message_stream_payload(
request_id: str,
message_id: str,
images: Any = None,
iac_code_model: str | None = None,
) -> dict[str, Any]:
parts = []
if prompt:
parts.append({"text": prompt})
parts.extend(_normalize_image_parts(images))
iac_code_metadata = {"cwd": cwd}
if iac_code_model:
stripped_model = iac_code_model.strip()
if stripped_model:
iac_code_metadata["iac_code_model"] = stripped_model
message: dict[str, Any] = {
"messageId": message_id,
"role": "ROLE_USER",
"parts": parts,
"metadata": {"iac_code": {"cwd": cwd}},
"metadata": {"iac_code": iac_code_metadata},
}
if context_id:
message["contextId"] = context_id
Expand Down Expand Up @@ -1386,6 +1392,9 @@ def render_index_html(config: DebuggerConfig) -> str:
<label for="cwd">cwd
<input id="cwd" value="__DEFAULT_CWD__" autocomplete="off">
</label>
<label for="iac-code-model">iac_code_model
<input id="iac-code-model" autocomplete="off">
</label>
<label for="context-id">contextId
<input id="context-id" autocomplete="off">
</label>
Expand Down Expand Up @@ -1583,6 +1592,7 @@ def render_index_html(config: DebuggerConfig) -> str:
return {
serverUrl: byId("server-url").value.trim(),
cwd: byId("cwd").value.trim(),
iacCodeModel: byId("iac-code-model").value.trim(),
contextId: byId("context-id").value.trim(),
taskId: byId("task-id").value.trim(),
activeTaskId: byId("active-task-id").value.trim(),
Expand Down Expand Up @@ -4271,6 +4281,7 @@ def render_index_html(config: DebuggerConfig) -> str:
const payload = {
serverUrl: controls.serverUrl,
cwd: controls.cwd,
iacCodeModel: controls.iacCodeModel,
contextId: controls.contextId || state.contextId,
taskId: streamTaskIdForControls(controls),
prompt: controls.prompt
Expand Down Expand Up @@ -4542,7 +4553,7 @@ def render_index_html(config: DebuggerConfig) -> str:
if (subtitle) {
subtitle.textContent = "Read-only exported debugger snapshot";
}
["server-url", "cwd", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
["server-url", "cwd", "iac-code-model", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
const element = byId(id);
if (element) {
element.readOnly = true;
Expand Down Expand Up @@ -4586,10 +4597,10 @@ def render_index_html(config: DebuggerConfig) -> str:
body.setAttribute("data-export-mode", "true");
}
clone.querySelectorAll("#debug-export-data").forEach((node) => node.remove());
["server-url", "cwd", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
["server-url", "cwd", "iac-code-model", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
copyControlValueToClone(clone, id);
});
["server-url", "cwd", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
["server-url", "cwd", "iac-code-model", "context-id", "task-id", "active-task-id", "prompt"].forEach((id) => {
const element = clone.querySelector(`#${cssEscape(id)}`);
if (element) {
element.setAttribute("readonly", "readonly");
Expand Down Expand Up @@ -4840,6 +4851,7 @@ def _open_sse_stream(server_url: str, payload: dict[str, Any], timeout: float =
def _message_stream_body(body: dict[str, Any]) -> tuple[str, dict[str, Any]]:
server_url = normalize_server_url(str(body.get("serverUrl", "")))
cwd = str(body.get("cwd", ""))
iac_code_model = str(body.get("iacCodeModel") or body.get("iac_code_model") or "")
prompt = str(body.get("prompt", ""))
context_id = str(body.get("contextId", ""))
task_id = str(body.get("taskId", ""))
Expand All @@ -4855,6 +4867,7 @@ def _message_stream_body(body: dict[str, Any]) -> tuple[str, dict[str, Any]]:
request_id=str(uuid.uuid4()),
message_id=str(uuid.uuid4()),
images=body.get("images"),
iac_code_model=iac_code_model,
)
return server_url, payload

Expand Down
23 changes: 22 additions & 1 deletion scripts/a2a/selling_console_web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
defaults: stateDefaults,
serverUrl: stateDefaults.serverUrl || "",
cwd: stateDefaults.cwd || "",
iacCodeModel: stateDefaults.iacCodeModel || "",
contextId: "",
pipelineTaskId: "",
activeTaskId: "",
Expand Down Expand Up @@ -1354,6 +1355,7 @@
return {
serverUrl: source.serverUrl || "",
cwd: source.cwd || "",
iacCodeModel: source.iacCodeModel || "",
contextId: source.contextId || "",
taskId: source.normalHandoffReady ? "" : source.activeTaskId || source.pipelineTaskId || "",
prompt: prompt || "",
Expand Down Expand Up @@ -2583,24 +2585,32 @@
const state = ensureState();
const serverInput = byId("server-url");
const cwdInput = byId("cwd");
const modelInput = byId("iac-code-model");
if (serverInput && "value" in serverInput && !serverInput.value && state.serverUrl) {
serverInput.value = state.serverUrl;
}
if (cwdInput && "value" in cwdInput && !cwdInput.value && state.cwd) {
cwdInput.value = state.cwd;
}
if (modelInput && "value" in modelInput && !modelInput.value && state.iacCodeModel) {
modelInput.value = state.iacCodeModel;
}
}

function syncStateFromConnectionControls() {
const state = ensureState();
const serverInput = byId("server-url");
const cwdInput = byId("cwd");
const modelInput = byId("iac-code-model");
if (serverInput && "value" in serverInput) {
state.serverUrl = String(serverInput.value || "").trim();
}
if (cwdInput && "value" in cwdInput) {
state.cwd = String(cwdInput.value || "").trim();
}
if (modelInput && "value" in modelInput) {
state.iacCodeModel = String(modelInput.value || "").trim();
}
return state;
}

Expand Down Expand Up @@ -3842,6 +3852,7 @@
const fields = [
["serverUrl", "Server URL", state.serverUrl || ""],
["cwd", "CWD", state.cwd || ""],
["iacCodeModel", "Model", state.iacCodeModel || ""],
["contextId", "Context ID", state.contextId || "未获取"],
["pipelineTaskId", "Pipeline Task", state.pipelineTaskId || "未获取"],
["activeTaskId", "Active Task", state.activeTaskId || "未获取"],
Expand Down Expand Up @@ -4220,6 +4231,7 @@
}
const serverInput = byId("server-url");
const cwdInput = byId("cwd");
const modelInput = byId("iac-code-model");
const sendButton = byId("send-button");
const composer = byId("composer-input");
const healthButton = byId("health-button");
Expand All @@ -4234,6 +4246,7 @@

addListener(serverInput, "input", syncStateFromConnectionControls);
addListener(cwdInput, "input", syncStateFromConnectionControls);
addListener(modelInput, "input", syncStateFromConnectionControls);
addListener(sendButton, "click", sendComposerMessage);
addListener(healthButton, "click", healthCheck);
addListener(fetchStateButton, "click", fetchState);
Expand All @@ -4246,7 +4259,15 @@
}
});
controller.bound = Boolean(
serverInput || cwdInput || sendButton || composer || healthButton || fetchStateButton || cancelButton || debugDrawer
serverInput ||
cwdInput ||
modelInput ||
sendButton ||
composer ||
healthButton ||
fetchStateButton ||
cancelButton ||
debugDrawer
);
}

Expand Down
4 changes: 4 additions & 0 deletions scripts/a2a/selling_console_web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ <h2>高可用标准方案</h2>
<span>CWD</span>
<input id="cwd" type="text" value="__DEFAULT_CWD_ATTR__">
</label>
<label>
<span>Model</span>
<input id="iac-code-model" type="text" placeholder="iac_code_model">
</label>
<div class="connection-actions">
<button id="health-button" class="secondary-button" type="button">连接检查</button>
<button id="fetch-state-button" class="secondary-button" type="button">同步状态</button>
Expand Down
9 changes: 9 additions & 0 deletions src/iac_code/a2a/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,15 @@ async def send_message(
cwd: str,
context_id: str | None = None,
model: str | None = None,
iac_code_api_key: str | None = None,
) -> A2AClientResponse:
payload = self._message_payload(
method="SendMessage",
prompt=prompt,
cwd=cwd,
context_id=context_id,
model=model,
iac_code_api_key=iac_code_api_key,
)
transport = self._make_transport_client(url)
response = await transport.send(payload)
Expand All @@ -152,13 +154,15 @@ async def stream_message(
cwd: str,
context_id: str | None = None,
model: str | None = None,
iac_code_api_key: str | None = None,
) -> AsyncIterator[dict[str, Any]]:
payload = self._message_payload(
method="SendStreamingMessage",
prompt=prompt,
cwd=cwd,
context_id=context_id,
model=model,
iac_code_api_key=iac_code_api_key,
)
transport = self._make_transport_client(url)
async for event in transport.stream(payload):
Expand Down Expand Up @@ -354,12 +358,17 @@ def _message_payload(
cwd: str,
context_id: str | None,
model: str | None,
iac_code_api_key: str | None,
) -> dict[str, Any]:
iac_code_metadata = {"cwd": cwd}
if model:
stripped_model = model.strip()
if stripped_model:
iac_code_metadata["iac_code_model"] = stripped_model
if iac_code_api_key:
stripped_api_key = iac_code_api_key.strip()
if stripped_api_key:
iac_code_metadata["iac_code_api_key"] = stripped_api_key
message: dict[str, Any] = {
"messageId": str(uuid.uuid4()),
"role": "ROLE_USER",
Expand Down
27 changes: 27 additions & 0 deletions src/iac_code/a2a/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@
_METADATA_MAX_DEPTH = 32
logger = logging.getLogger(__name__)
A2APermissionResolver: TypeAlias = Callable[[PermissionRequestEvent], "bool | Awaitable[bool]"]
IAC_CODE_SESSION_ID_METADATA_KEY = "iacCodeSessionId"


def iac_code_session_metadata(session_id: str) -> dict[str, Any]:
return {"iac_code": {IAC_CODE_SESSION_ID_METADATA_KEY: session_id}}


def with_iac_code_session_metadata(metadata: dict[str, Any] | None, session_id: str | None) -> dict[str, Any] | None:
if not session_id:
return metadata
merged = dict(metadata or {})
iac_code = dict(merged.get("iac_code") or {})
iac_code[IAC_CODE_SESSION_ID_METADATA_KEY] = session_id
merged["iac_code"] = iac_code
return merged


def _truncate(value: Any, *, _depth: int = 0) -> Any:
Expand Down Expand Up @@ -144,12 +159,14 @@ async def _enqueue_status(
state: int,
message: Message | None = None,
metadata: dict[str, Any] | None = None,
iac_code_session_id: str | None = None,
) -> None:
update = TaskStatusUpdateEvent(
task_id=task_id,
context_id=context_id,
status=TaskStatus(state=TaskState.Name(state), message=message),
)
metadata = with_iac_code_session_metadata(metadata, iac_code_session_id)
if metadata is not None:
ParseDict(metadata, update.metadata)
await event_queue.enqueue_event(update)
Expand All @@ -165,6 +182,7 @@ async def publish_stream_event(
permission_resolver: A2APermissionResolver | None = None,
auto_approve_permissions: bool = False,
exposure_types: Any = None,
iac_code_session_id: str | None = None,
) -> str | None:
enabled_exposure_types = normalize_a2a_exposure_types(exposure_types)

Expand All @@ -177,6 +195,7 @@ async def publish_stream_event(
context_id=context_id,
state=TaskState.TASK_STATE_WORKING,
message=_agent_text_message(task_id=task_id, context_id=context_id, text=event.text),
iac_code_session_id=iac_code_session_id,
)
return event.text

Expand All @@ -189,6 +208,7 @@ async def publish_stream_event(
context_id=context_id,
state=TaskState.TASK_STATE_WORKING,
metadata={"iac_code": {"thinking": {"type": "raw_thinking", "text": _truncate(event.text)}}},
iac_code_session_id=iac_code_session_id,
)
return None

Expand All @@ -201,6 +221,7 @@ async def publish_stream_event(
context_id=context_id,
state=TaskState.TASK_STATE_WORKING,
metadata={"iac_code": {"tool": {"status": "started", "toolUseId": event.tool_use_id, "name": event.name}}},
iac_code_session_id=iac_code_session_id,
)
return None

Expand All @@ -221,6 +242,7 @@ async def publish_stream_event(
}
}
},
iac_code_session_id=iac_code_session_id,
)
return None

Expand All @@ -242,6 +264,7 @@ async def publish_stream_event(
}
}
},
iac_code_session_id=iac_code_session_id,
)
return None

Expand Down Expand Up @@ -270,6 +293,7 @@ async def publish_stream_event(
context_id=context_id,
state=TaskState.TASK_STATE_WORKING,
metadata={"iac_code": {"tool": tool_metadata}},
iac_code_session_id=iac_code_session_id,
)
return None

Expand Down Expand Up @@ -297,6 +321,7 @@ async def publish_stream_event(
}
}
},
iac_code_session_id=iac_code_session_id,
)
return None

Expand All @@ -315,6 +340,7 @@ async def publish_stream_event(
}
}
},
iac_code_session_id=iac_code_session_id,
)
return None

Expand All @@ -336,6 +362,7 @@ async def publish_stream_event(
state=state,
message=_agent_text_message(task_id=task_id, context_id=context_id, text=text),
metadata={"iac_code": {"error": error_metadata}},
iac_code_session_id=iac_code_session_id,
)
return None

Expand Down
Loading
Loading