{"owner":"ilya-zlobintsev","repo":"LACT","hasSkills":true,"totalSkillsCount":1,"totalTokensCount":1125,"categories":["project-spec"],"hasMcp":false,"mcpConfig":null,"found":["docs/API.md"],"skills":{"docs/API.md":"# Description\n\nThe LACT Daemon exposes a JSON API over a unix socket or TCP, available on `/run/lactd.sock` or an arbitrary TCP port. You can configure who has access to the unix socket in `/etc/lact/config.yaml` in the `daemon.admin_group` or `daemon.admin_user` field. The TCP listener is disabled by default for security reasons, see [this README section](../README.md#remote-management) for how to enable it.\n\nThe API expects newline-separated JSON objects, and returns a JSON object for every request.\n\nThe general format of requests looks like:\n```\n{\"command\": \"command_name\", \"args\": {}}\n```\nNote that the type of `args` depends on the specific request, and may be omitted in some cases.\n\nThe response looks like this:\n```\n{\"status\": \"ok|error\", \"data\": {}}\n```\nSame as `args` in requests, `data` can be of a different type and may not be present depending on the specific request.\n\nYou can try sending commands to socket interactively with `ncat`:\n```\necho '{\"command\": \"list_devices\"}' | ncat -U /run/lactd.sock\n```\nExample response:\n```\n{\"status\":\"ok\",\"data\":[{\"id\":\"1002:687F-1043:0555-0000:0b:00.0\",\"name\":\"Vega 10 XL/XT [Radeon RX Vega 56/64]\"}]}\n```\n\nHere's an example of calling the API with arguments to change a profile:\n```\necho '{\"command\": \"set_profile\", \"args\": {\"name\":\"name-of-the-profile\"}}' | ncat -U /run/lactd.sock\n```\nIn this code, `name-of-the-profile` should be replaced with the name of a profile that you've already created in LACT.\n\n\n# Commands\n\nThe primary API commands for GPU configuration are `get_gpu_config` and `set_gpu_config`. It uses the same configuration format as described in [CONFIG.md](./CONFIG.md), except as JSON instead of YAML.\n\nTo change a setting through the API, you should fetch the current config, modify it, and then set it.\nAdditionally, each config change must be confirmed, or it will be automatically reverted after a short time period (5 seconds by default). This is needed to avoid saving settings that instantly crash a system.\n\n**Deprecated commands**: there is a number of `set_` commands in the API that change individual settings. They are still functional for backwards compatibility purposes, but the `get_gpu_config`/`set_gpu_config` commands should be preferred instead.\n\nExample: how to set the power limit through the API:\n\n1. Get GPU id\n```\n> echo '{\"command\": \"list_devices\"}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":[{\"id\":\"10DE:2704-1462:5110-0000:09:00.0\",\"name\":\"AD103 [GeForce RTX 4080]\"}]}\n```\n\n2. Get current config\n```\n> echo '{\"command\": \"get_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\"}}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":{\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":320.0}}\n```\n\n3. Set a new config\n\nThe `power_cap` field has been changed from the previous config\n```\n> echo '{\"command\": \"set_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\", \"config\": {\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":340.0}}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":5}\n```\n\n4. Confirm new config\n```\n> echo '{\"command\": \"confirm_pending_config\", \"args\": {\"command\": \"confirm\"}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":null}\n```\n\nFor the full list of available commands and responses, you can look at the source code of the schema: [requests](../lact-schema/src/request.rs), [the basic response structure](../lact-schema/src/response.rs) and [all possible types](../lact-schema/src/lib.rs).\n\nIt should also be fairly easy to figure out the API by trial and error, as the error message are quite verbose:\n\n```\necho '{\"command\": \"test\"}' | ncat -U /run/lactd.sock\n\n{\"status\":\"error\",\"data\":\"Failed to deserialize request: unknown variant `test`, expected one of `ping`, `list_devices`, `system_info`, `device_info`, `device_stats`, `device_clocks_info`, `set_fan_control`, `set_power_cap`, `set_performance_level`, `set_clocks_value` at line 1 column 18\"}\n```\n\n# Rust\n\nIf you want to connect to the socket from a Rust program, you can simply import either the `lact-client` or `lact-schema` (if you want to write a custom client) crates from this repository.\n"},"files":{"docs/API.md":"# Description\n\nThe LACT Daemon exposes a JSON API over a unix socket or TCP, available on `/run/lactd.sock` or an arbitrary TCP port. You can configure who has access to the unix socket in `/etc/lact/config.yaml` in the `daemon.admin_group` or `daemon.admin_user` field. The TCP listener is disabled by default for security reasons, see [this README section](../README.md#remote-management) for how to enable it.\n\nThe API expects newline-separated JSON objects, and returns a JSON object for every request.\n\nThe general format of requests looks like:\n```\n{\"command\": \"command_name\", \"args\": {}}\n```\nNote that the type of `args` depends on the specific request, and may be omitted in some cases.\n\nThe response looks like this:\n```\n{\"status\": \"ok|error\", \"data\": {}}\n```\nSame as `args` in requests, `data` can be of a different type and may not be present depending on the specific request.\n\nYou can try sending commands to socket interactively with `ncat`:\n```\necho '{\"command\": \"list_devices\"}' | ncat -U /run/lactd.sock\n```\nExample response:\n```\n{\"status\":\"ok\",\"data\":[{\"id\":\"1002:687F-1043:0555-0000:0b:00.0\",\"name\":\"Vega 10 XL/XT [Radeon RX Vega 56/64]\"}]}\n```\n\nHere's an example of calling the API with arguments to change a profile:\n```\necho '{\"command\": \"set_profile\", \"args\": {\"name\":\"name-of-the-profile\"}}' | ncat -U /run/lactd.sock\n```\nIn this code, `name-of-the-profile` should be replaced with the name of a profile that you've already created in LACT.\n\n\n# Commands\n\nThe primary API commands for GPU configuration are `get_gpu_config` and `set_gpu_config`. It uses the same configuration format as described in [CONFIG.md](./CONFIG.md), except as JSON instead of YAML.\n\nTo change a setting through the API, you should fetch the current config, modify it, and then set it.\nAdditionally, each config change must be confirmed, or it will be automatically reverted after a short time period (5 seconds by default). This is needed to avoid saving settings that instantly crash a system.\n\n**Deprecated commands**: there is a number of `set_` commands in the API that change individual settings. They are still functional for backwards compatibility purposes, but the `get_gpu_config`/`set_gpu_config` commands should be preferred instead.\n\nExample: how to set the power limit through the API:\n\n1. Get GPU id\n```\n> echo '{\"command\": \"list_devices\"}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":[{\"id\":\"10DE:2704-1462:5110-0000:09:00.0\",\"name\":\"AD103 [GeForce RTX 4080]\"}]}\n```\n\n2. Get current config\n```\n> echo '{\"command\": \"get_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\"}}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":{\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":320.0}}\n```\n\n3. Set a new config\n\nThe `power_cap` field has been changed from the previous config\n```\n> echo '{\"command\": \"set_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\", \"config\": {\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":340.0}}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":5}\n```\n\n4. Confirm new config\n```\n> echo '{\"command\": \"confirm_pending_config\", \"args\": {\"command\": \"confirm\"}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":null}\n```\n\nFor the full list of available commands and responses, you can look at the source code of the schema: [requests](../lact-schema/src/request.rs), [the basic response structure](../lact-schema/src/response.rs) and [all possible types](../lact-schema/src/lib.rs).\n\nIt should also be fairly easy to figure out the API by trial and error, as the error message are quite verbose:\n\n```\necho '{\"command\": \"test\"}' | ncat -U /run/lactd.sock\n\n{\"status\":\"error\",\"data\":\"Failed to deserialize request: unknown variant `test`, expected one of `ping`, `list_devices`, `system_info`, `device_info`, `device_stats`, `device_clocks_info`, `set_fan_control`, `set_power_cap`, `set_performance_level`, `set_clocks_value` at line 1 column 18\"}\n```\n\n# Rust\n\nIf you want to connect to the socket from a Rust program, you can simply import either the `lact-client` or `lact-schema` (if you want to write a custom client) crates from this repository.\n"},"items":[{"name":"API.md","path":"docs/API.md","rawUrl":"https://raw.githubusercontent.com/ilya-zlobintsev/LACT/HEAD/docs/API.md","title":"docs - API Interface Contract & Specifications","category":"project-spec","format":"markdown","content":"# Description\n\nThe LACT Daemon exposes a JSON API over a unix socket or TCP, available on `/run/lactd.sock` or an arbitrary TCP port. You can configure who has access to the unix socket in `/etc/lact/config.yaml` in the `daemon.admin_group` or `daemon.admin_user` field. The TCP listener is disabled by default for security reasons, see [this README section](../README.md#remote-management) for how to enable it.\n\nThe API expects newline-separated JSON objects, and returns a JSON object for every request.\n\nThe general format of requests looks like:\n```\n{\"command\": \"command_name\", \"args\": {}}\n```\nNote that the type of `args` depends on the specific request, and may be omitted in some cases.\n\nThe response looks like this:\n```\n{\"status\": \"ok|error\", \"data\": {}}\n```\nSame as `args` in requests, `data` can be of a different type and may not be present depending on the specific request.\n\nYou can try sending commands to socket interactively with `ncat`:\n```\necho '{\"command\": \"list_devices\"}' | ncat -U /run/lactd.sock\n```\nExample response:\n```\n{\"status\":\"ok\",\"data\":[{\"id\":\"1002:687F-1043:0555-0000:0b:00.0\",\"name\":\"Vega 10 XL/XT [Radeon RX Vega 56/64]\"}]}\n```\n\nHere's an example of calling the API with arguments to change a profile:\n```\necho '{\"command\": \"set_profile\", \"args\": {\"name\":\"name-of-the-profile\"}}' | ncat -U /run/lactd.sock\n```\nIn this code, `name-of-the-profile` should be replaced with the name of a profile that you've already created in LACT.\n\n\n# Commands\n\nThe primary API commands for GPU configuration are `get_gpu_config` and `set_gpu_config`. It uses the same configuration format as described in [CONFIG.md](./CONFIG.md), except as JSON instead of YAML.\n\nTo change a setting through the API, you should fetch the current config, modify it, and then set it.\nAdditionally, each config change must be confirmed, or it will be automatically reverted after a short time period (5 seconds by default). This is needed to avoid saving settings that instantly crash a system.\n\n**Deprecated commands**: there is a number of `set_` commands in the API that change individual settings. They are still functional for backwards compatibility purposes, but the `get_gpu_config`/`set_gpu_config` commands should be preferred instead.\n\nExample: how to set the power limit through the API:\n\n1. Get GPU id\n```\n> echo '{\"command\": \"list_devices\"}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":[{\"id\":\"10DE:2704-1462:5110-0000:09:00.0\",\"name\":\"AD103 [GeForce RTX 4080]\"}]}\n```\n\n2. Get current config\n```\n> echo '{\"command\": \"get_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\"}}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":{\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":320.0}}\n```\n\n3. Set a new config\n\nThe `power_cap` field has been changed from the previous config\n```\n> echo '{\"command\": \"set_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\", \"config\": {\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":340.0}}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":5}\n```\n\n4. Confirm new config\n```\n> echo '{\"command\": \"confirm_pending_config\", \"args\": {\"command\": \"confirm\"}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":null}\n```\n\nFor the full list of available commands and responses, you can look at the source code of the schema: [requests](../lact-schema/src/request.rs), [the basic response structure](../lact-schema/src/response.rs) and [all possible types](../lact-schema/src/lib.rs).\n\nIt should also be fairly easy to figure out the API by trial and error, as the error message are quite verbose:\n\n```\necho '{\"command\": \"test\"}' | ncat -U /run/lactd.sock\n\n{\"status\":\"error\",\"data\":\"Failed to deserialize request: unknown variant `test`, expected one of `ping`, `list_devices`, `system_info`, `device_info`, `device_stats`, `device_clocks_info`, `set_fan_control`, `set_power_cap`, `set_performance_level`, `set_clocks_value` at line 1 column 18\"}\n```\n\n# Rust\n\nIf you want to connect to the socket from a Rust program, you can simply import either the `lact-client` or `lact-schema` (if you want to write a custom client) crates from this repository.\n","isInternal":false,"tokens":1125,"sizeBytes":4498}],"systemPromptSnippet":"<agent_rules repository=\"ilya-zlobintsev/LACT\">\n\n<!-- Skill/Rule: docs - API Interface Contract & Specifications (docs/API.md) -->\n# Description\n\nThe LACT Daemon exposes a JSON API over a unix socket or TCP, available on `/run/lactd.sock` or an arbitrary TCP port. You can configure who has access to the unix socket in `/etc/lact/config.yaml` in the `daemon.admin_group` or `daemon.admin_user` field. The TCP listener is disabled by default for security reasons, see [this README section](../README.md#remote-management) for how to enable it.\n\nThe API expects newline-separated JSON objects, and returns a JSON object for every request.\n\nThe general format of requests looks like:\n```\n{\"command\": \"command_name\", \"args\": {}}\n```\nNote that the type of `args` depends on the specific request, and may be omitted in some cases.\n\nThe response looks like this:\n```\n{\"status\": \"ok|error\", \"data\": {}}\n```\nSame as `args` in requests, `data` can be of a different type and may not be present depending on the specific request.\n\nYou can try sending commands to socket interactively with `ncat`:\n```\necho '{\"command\": \"list_devices\"}' | ncat -U /run/lactd.sock\n```\nExample response:\n```\n{\"status\":\"ok\",\"data\":[{\"id\":\"1002:687F-1043:0555-0000:0b:00.0\",\"name\":\"Vega 10 XL/XT [Radeon RX Vega 56/64]\"}]}\n```\n\nHere's an example of calling the API with arguments to change a profile:\n```\necho '{\"command\": \"set_profile\", \"args\": {\"name\":\"name-of-the-profile\"}}' | ncat -U /run/lactd.sock\n```\nIn this code, `name-of-the-profile` should be replaced with the name of a profile that you've already created in LACT.\n\n\n# Commands\n\nThe primary API commands for GPU configuration are `get_gpu_config` and `set_gpu_config`. It uses the same configuration format as described in [CONFIG.md](./CONFIG.md), except as JSON instead of YAML.\n\nTo change a setting through the API, you should fetch the current config, modify it, and then set it.\nAdditionally, each config change must be confirmed, or it will be automatically reverted after a short time period (5 seconds by default). This is needed to avoid saving settings that instantly crash a system.\n\n**Deprecated commands**: there is a number of `set_` commands in the API that change individual settings. They are still functional for backwards compatibility purposes, but the `get_gpu_config`/`set_gpu_config` commands should be preferred instead.\n\nExample: how to set the power limit through the API:\n\n1. Get GPU id\n```\n> echo '{\"command\": \"list_devices\"}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":[{\"id\":\"10DE:2704-1462:5110-0000:09:00.0\",\"name\":\"AD103 [GeForce RTX 4080]\"}]}\n```\n\n2. Get current config\n```\n> echo '{\"command\": \"get_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\"}}' | nc -U /run/lactd.sock \n{\"status\":\"ok\",\"data\":{\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":320.0}}\n```\n\n3. Set a new config\n\nThe `power_cap` field has been changed from the previous config\n```\n> echo '{\"command\": \"set_gpu_config\", \"args\": {\"id\": \"10DE:2704-1462:5110-0000:09:00.0\", \"config\": {\"fan_control_enabled\":false,\"fan_control_settings\":{\"mode\":\"static\",\"static_speed\":1.0,\"temperature_key\":\"edge\",\"interval_ms\":500,\"curve\":{\"40\":0.3,\"50\":0.35,\"60\":0.5,\"70\":0.75,\"80\":1.0},\"spindown_delay_ms\":2856,\"change_threshold\":2},\"power_cap\":340.0}}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":5}\n```\n\n4. Confirm new config\n```\n> echo '{\"command\": \"confirm_pending_config\", \"args\": {\"command\": \"confirm\"}}' | nc -U /run/lactd.sock\n{\"status\":\"ok\",\"data\":null}\n```\n\nFor the full list of available commands and responses, you can look at the source code of the schema: [requests](../lact-schema/src/request.rs), [the basic response structure](../lact-schema/src/response.rs) and [all possible types](../lact-schema/src/lib.rs).\n\nIt should also be fairly easy to figure out the API by trial and error, as the error message are quite verbose:\n\n```\necho '{\"command\": \"test\"}' | ncat -U /run/lactd.sock\n\n{\"status\":\"error\",\"data\":\"Failed to deserialize request: unknown variant `test`, expected one of `ping`, `list_devices`, `system_info`, `device_info`, `device_stats`, `device_clocks_info`, `set_fan_control`, `set_power_cap`, `set_performance_level`, `set_clocks_value` at line 1 column 18\"}\n```\n\n# Rust\n\nIf you want to connect to the socket from a Rust program, you can simply import either the `lact-client` or `lact-schema` (if you want to write a custom client) crates from this repository.\n\n\n</agent_rules>"}