fireworks2bedrock-migrate 0.0.1__tar.gz

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.
@@ -0,0 +1,28 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ venv/
7
+ dist/
8
+ build/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+
13
+ # Node
14
+ node_modules/
15
+ js/dist/
16
+ *.tsbuildinfo
17
+
18
+ # Environment and secrets
19
+ .env
20
+ .env.*
21
+ !.env.example
22
+ *.pem
23
+ *accessKeys*.csv
24
+
25
+ # OS / editors
26
+ .DS_Store
27
+ .idea/
28
+ .vscode/
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: fireworks2bedrock-migrate
3
+ Version: 0.0.1
4
+ Summary: One-shot migration of Kimi K3 inference from Fireworks to Amazon Bedrock for Python repositories
5
+ Project-URL: Repository, https://github.com/HolboxAI/fireworks2bedrock-migrate
6
+ License-Expression: Apache-2.0
7
+ Requires-Python: >=3.9
8
+ Requires-Dist: libcst>=1.1.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest; extra == 'dev'
11
+ Description-Content-Type: text/markdown
12
+
13
+ # fireworks2bedrock-migrate
14
+
15
+ One-shot migration of **Kimi K3** inference from **Fireworks** to **Amazon Bedrock**, for **Python** repositories. One command scans the repository, rewrites the inference calls, and opens a pull request. The model does not change — only the backend does.
16
+
17
+ > JavaScript / TypeScript repositories use the npm package instead: `npx -y fireworks2bedrock-migrate migrate --pr`.
18
+
19
+ ---
20
+
21
+ ## For coding agents (use this README as a skill)
22
+
23
+ This package is meant to be driven by a coding agent. When asked to *"migrate this repository from Fireworks Kimi K3 to Bedrock"*, follow this workflow exactly and do not improvise on the parts it covers.
24
+
25
+ ### Step 1 — Scan
26
+
27
+ ```bash
28
+ uvx fireworks2bedrock-migrate scan <repo> --json
29
+ ```
30
+
31
+ Read the `findings` and bucket them:
32
+
33
+ | classification | meaning |
34
+ |---|---|
35
+ | `MIGRATE` | will be rewritten |
36
+ | `BLOCK` | left untouched (fine-tuned models, non-inference APIs, adapters, dedicated deployments) |
37
+ | `REVIEW` | needs a decision (runtime `base_url` clients, computed model IDs, raw HTTP) |
38
+
39
+ ### Step 2 — Migrate and open the pull request
40
+
41
+ ```bash
42
+ uvx fireworks2bedrock-migrate migrate <repo> --pr --json
43
+ ```
44
+
45
+ This creates the branch `f2b/kimi-k3-bedrock`, rewrites the `MIGRATE` files, drops in the `llm_client.py` helper and `f2b.json` routing config, adds the runtime dependencies, writes `BEDROCK_MIGRATION.md`, and opens the pull request.
46
+
47
+ ### Step 3 — Act on the exit code
48
+
49
+ | code | meaning | what to do |
50
+ |---|---|---|
51
+ | `0` | migration applied (and PR opened with `--pr`) | go to Step 4 |
52
+ | `20` | nothing to migrate, or everything is `BLOCK` | report why; edit nothing |
53
+ | `30` | environment problem (dirty git tree, no `origin` remote) | report the message; edit nothing |
54
+
55
+ ### Step 4 — Verify
56
+
57
+ The tool does not run the repository's own tests yet (`checks` in the JSON is reserved for that), so the agent verifies:
58
+
59
+ 1. Read `review_items` from the JSON output — each one needs a decision before deploy.
60
+ 2. Run the repository's own checks: `pytest -q`, plus lint/type-check/build from `.github/workflows/*.yml` or `pyproject.toml`.
61
+ 3. Confirm the diff touches only `MIGRATE` files plus the helper and config.
62
+ 4. Fix only failures in the files the tool listed, then push to the branch.
63
+
64
+ ### Step 5 — Report
65
+
66
+ Report the pull request URL, the `BLOCK` items that were deliberately left alone, and any `REVIEW` items still needing attention.
67
+
68
+ ### Rules — never break these
69
+
70
+ - Never edit a file or finding the tool classified `BLOCK`.
71
+ - Never hand-edit a model ID; the tool and `f2b.json` own that mapping.
72
+ - Never touch infrastructure files unless the tool lists them as `REVIEW`.
73
+ - Do not add setup steps for the developer — one command is the whole experience.
74
+
75
+ ---
76
+
77
+ ## What the migration changes
78
+
79
+ - Model ID `accounts/fireworks/models/kimi-k3` → `global.moonshotai.kimi-k3` (`us.moonshotai.kimi-k3` with `--us-only`)
80
+ - `OpenAI(...)` / `Fireworks(...)` / `AsyncFireworks(...)` / `ChatFireworks(...)` → `get_llm_client()` / `get_async_llm_client()` / `ChatOpenAI(model=KIMI_K3, ...)`
81
+ - Adds the `llm_client.py` helper, `f2b.json` routing config, and the runtime deps `openai` + `aws-bedrock-token-generator`
82
+ - Writes `BEDROCK_MIGRATION.md`: full change log, everything left untouched, the IAM policy to attach, and rollback steps
83
+
84
+ ## Rollback
85
+
86
+ Set `F2B_BACKEND=fireworks` to route back to Fireworks with no code change.
87
+
88
+ ## CLI reference
89
+
90
+ ```
91
+ fireworks2bedrock-migrate scan [path] [--json]
92
+ fireworks2bedrock-migrate migrate [path] [--pr] [--us-only] [--region <r>] [--json] [--no-git]
93
+ ```
94
+
95
+ - `--pr` pushes the branch and opens a pull request (without it the commit stays local).
96
+ - `--us-only` targets the `us.moonshotai.kimi-k3` profile instead of `global.`.
97
+ - `--no-git` skips branch/commit/push (for testing).
98
+
99
+ ## Scope
100
+
101
+ | Supported | Not supported (left as `BLOCK`) |
102
+ |---|---|
103
+ | Fireworks **base** Kimi K3 inference | fine-tuned models, LoRA adapters, dedicated deployments |
104
+ | OpenAI SDK, Fireworks SDK, LangChain, raw HTTP inference calls | fine-tuning, embeddings, datasets, batch, rerank, other non-inference APIs |
105
+ | Python repositories | other models and providers |
@@ -0,0 +1,93 @@
1
+ # fireworks2bedrock-migrate
2
+
3
+ One-shot migration of **Kimi K3** inference from **Fireworks** to **Amazon Bedrock**, for **Python** repositories. One command scans the repository, rewrites the inference calls, and opens a pull request. The model does not change — only the backend does.
4
+
5
+ > JavaScript / TypeScript repositories use the npm package instead: `npx -y fireworks2bedrock-migrate migrate --pr`.
6
+
7
+ ---
8
+
9
+ ## For coding agents (use this README as a skill)
10
+
11
+ This package is meant to be driven by a coding agent. When asked to *"migrate this repository from Fireworks Kimi K3 to Bedrock"*, follow this workflow exactly and do not improvise on the parts it covers.
12
+
13
+ ### Step 1 — Scan
14
+
15
+ ```bash
16
+ uvx fireworks2bedrock-migrate scan <repo> --json
17
+ ```
18
+
19
+ Read the `findings` and bucket them:
20
+
21
+ | classification | meaning |
22
+ |---|---|
23
+ | `MIGRATE` | will be rewritten |
24
+ | `BLOCK` | left untouched (fine-tuned models, non-inference APIs, adapters, dedicated deployments) |
25
+ | `REVIEW` | needs a decision (runtime `base_url` clients, computed model IDs, raw HTTP) |
26
+
27
+ ### Step 2 — Migrate and open the pull request
28
+
29
+ ```bash
30
+ uvx fireworks2bedrock-migrate migrate <repo> --pr --json
31
+ ```
32
+
33
+ This creates the branch `f2b/kimi-k3-bedrock`, rewrites the `MIGRATE` files, drops in the `llm_client.py` helper and `f2b.json` routing config, adds the runtime dependencies, writes `BEDROCK_MIGRATION.md`, and opens the pull request.
34
+
35
+ ### Step 3 — Act on the exit code
36
+
37
+ | code | meaning | what to do |
38
+ |---|---|---|
39
+ | `0` | migration applied (and PR opened with `--pr`) | go to Step 4 |
40
+ | `20` | nothing to migrate, or everything is `BLOCK` | report why; edit nothing |
41
+ | `30` | environment problem (dirty git tree, no `origin` remote) | report the message; edit nothing |
42
+
43
+ ### Step 4 — Verify
44
+
45
+ The tool does not run the repository's own tests yet (`checks` in the JSON is reserved for that), so the agent verifies:
46
+
47
+ 1. Read `review_items` from the JSON output — each one needs a decision before deploy.
48
+ 2. Run the repository's own checks: `pytest -q`, plus lint/type-check/build from `.github/workflows/*.yml` or `pyproject.toml`.
49
+ 3. Confirm the diff touches only `MIGRATE` files plus the helper and config.
50
+ 4. Fix only failures in the files the tool listed, then push to the branch.
51
+
52
+ ### Step 5 — Report
53
+
54
+ Report the pull request URL, the `BLOCK` items that were deliberately left alone, and any `REVIEW` items still needing attention.
55
+
56
+ ### Rules — never break these
57
+
58
+ - Never edit a file or finding the tool classified `BLOCK`.
59
+ - Never hand-edit a model ID; the tool and `f2b.json` own that mapping.
60
+ - Never touch infrastructure files unless the tool lists them as `REVIEW`.
61
+ - Do not add setup steps for the developer — one command is the whole experience.
62
+
63
+ ---
64
+
65
+ ## What the migration changes
66
+
67
+ - Model ID `accounts/fireworks/models/kimi-k3` → `global.moonshotai.kimi-k3` (`us.moonshotai.kimi-k3` with `--us-only`)
68
+ - `OpenAI(...)` / `Fireworks(...)` / `AsyncFireworks(...)` / `ChatFireworks(...)` → `get_llm_client()` / `get_async_llm_client()` / `ChatOpenAI(model=KIMI_K3, ...)`
69
+ - Adds the `llm_client.py` helper, `f2b.json` routing config, and the runtime deps `openai` + `aws-bedrock-token-generator`
70
+ - Writes `BEDROCK_MIGRATION.md`: full change log, everything left untouched, the IAM policy to attach, and rollback steps
71
+
72
+ ## Rollback
73
+
74
+ Set `F2B_BACKEND=fireworks` to route back to Fireworks with no code change.
75
+
76
+ ## CLI reference
77
+
78
+ ```
79
+ fireworks2bedrock-migrate scan [path] [--json]
80
+ fireworks2bedrock-migrate migrate [path] [--pr] [--us-only] [--region <r>] [--json] [--no-git]
81
+ ```
82
+
83
+ - `--pr` pushes the branch and opens a pull request (without it the commit stays local).
84
+ - `--us-only` targets the `us.moonshotai.kimi-k3` profile instead of `global.`.
85
+ - `--no-git` skips branch/commit/push (for testing).
86
+
87
+ ## Scope
88
+
89
+ | Supported | Not supported (left as `BLOCK`) |
90
+ |---|---|
91
+ | Fireworks **base** Kimi K3 inference | fine-tuned models, LoRA adapters, dedicated deployments |
92
+ | OpenAI SDK, Fireworks SDK, LangChain, raw HTTP inference calls | fine-tuning, embeddings, datasets, batch, rerank, other non-inference APIs |
93
+ | Python repositories | other models and providers |
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "fireworks2bedrock-migrate"
7
+ version = "0.0.1"
8
+ description = "One-shot migration of Kimi K3 inference from Fireworks to Amazon Bedrock for Python repositories"
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.9"
12
+ dependencies = ["libcst>=1.1.0"]
13
+
14
+ [project.optional-dependencies]
15
+ dev = ["pytest"]
16
+
17
+ [project.scripts]
18
+ fireworks2bedrock-migrate = "fireworks2bedrock_migrate.cli:main"
19
+
20
+ [project.urls]
21
+ Repository = "https://github.com/HolboxAI/fireworks2bedrock-migrate"
@@ -0,0 +1,3 @@
1
+ """One-shot migration of Kimi K3 inference from Fireworks to Amazon Bedrock."""
2
+
3
+ __version__ = "0.0.1"
@@ -0,0 +1,145 @@
1
+ """Command-line entry point."""
2
+
3
+ import argparse
4
+ import json
5
+ import os
6
+ import sys
7
+ from collections import Counter
8
+
9
+ from . import __version__
10
+ from .migrate import migrate_repo
11
+ from .scan import detect_language, scan_repo
12
+
13
+
14
+ def _build_parser():
15
+ parser = argparse.ArgumentParser(
16
+ prog="fireworks2bedrock-migrate",
17
+ description="Migrate Kimi K3 inference from Fireworks to Amazon Bedrock.",
18
+ )
19
+ parser.add_argument("--version", action="version", version=__version__)
20
+ sub = parser.add_subparsers(dest="command", required=True)
21
+
22
+ scan = sub.add_parser("scan", help="List Fireworks usage and how each item would be handled")
23
+ scan.add_argument("path", nargs="?", default=".")
24
+ scan.add_argument("--json", action="store_true", help="Machine-readable output on stdout")
25
+
26
+ migrate = sub.add_parser("migrate", help="Apply the migration on a new branch")
27
+ migrate.add_argument("path", nargs="?", default=".")
28
+ migrate.add_argument("--pr", action="store_true", help="Push the branch and open a pull request")
29
+ migrate.add_argument("--us-only", action="store_true", help="Use the us. inference profile instead of global.")
30
+ migrate.add_argument("--region", help="Default AWS region for the helper fallback")
31
+ migrate.add_argument("--json", action="store_true", help="Machine-readable output on stdout")
32
+ migrate.add_argument("--no-git", action="store_true", help="Do not branch/commit/push (for testing)")
33
+
34
+ return parser
35
+
36
+
37
+ def _cmd_scan(args) -> int:
38
+ path = os.path.abspath(args.path)
39
+ if not os.path.isdir(path):
40
+ print(f"error: not a directory: {path}", file=sys.stderr)
41
+ return 30
42
+
43
+ language = detect_language(path)
44
+ findings = scan_repo(path)
45
+ code = _exit_code(findings)
46
+
47
+ if args.json:
48
+ payload = {
49
+ "version": __version__,
50
+ "repo": path,
51
+ "language": language,
52
+ "branch": None,
53
+ "pr_url": None,
54
+ "findings": [f.to_dict() for f in findings],
55
+ "checks": [],
56
+ "review_items": [],
57
+ "exit_code": code,
58
+ }
59
+ print(json.dumps(payload, indent=2))
60
+ else:
61
+ _print_human(language, path, findings)
62
+
63
+ return code
64
+
65
+
66
+ def _exit_code(findings) -> int:
67
+ if not findings:
68
+ return 20
69
+ if all(f.classification == "BLOCK" for f in findings):
70
+ return 20
71
+ return 0
72
+
73
+
74
+ def _print_human(language: str, path: str, findings) -> None:
75
+ print(f"repo: {path}")
76
+ print(f"language: {language}")
77
+ print(f"findings: {len(findings)}")
78
+ print()
79
+ if not findings:
80
+ print("No Fireworks Kimi K3 usage found.")
81
+ return
82
+
83
+ file_width = min(max(len(f.file) for f in findings), 36)
84
+ header = f"{'CLASS':<8} {'LINE':>5} {'KIND':<22} {'FILE':<{file_width}} DETAIL"
85
+ print(header)
86
+ print("-" * len(header))
87
+ for f in findings:
88
+ file_col = f.file if len(f.file) <= file_width else "…" + f.file[-(file_width - 1):]
89
+ print(f"{f.classification:<8} {f.line:>5} {f.kind:<22} {file_col:<{file_width}} {f.detail}")
90
+
91
+ counts = Counter(f.classification for f in findings)
92
+ print()
93
+ parts = [f"{cls}={counts[cls]}" for cls in ("MIGRATE", "BLOCK", "REVIEW") if counts[cls]]
94
+ print("summary: " + ", ".join(parts))
95
+
96
+
97
+ def _cmd_migrate(args) -> int:
98
+ path = os.path.abspath(args.path)
99
+ if not os.path.isdir(path):
100
+ print(f"error: not a directory: {path}", file=sys.stderr)
101
+ return 30
102
+
103
+ result = migrate_repo(
104
+ path,
105
+ us_only=args.us_only,
106
+ pr=args.pr,
107
+ region=args.region,
108
+ apply_git=not args.no_git,
109
+ )
110
+
111
+ if args.json:
112
+ payload = {
113
+ "version": __version__,
114
+ "repo": path,
115
+ "language": result.language,
116
+ "branch": result.branch,
117
+ "pr_url": result.pr_url,
118
+ "findings": [f.to_dict() for f in result.findings],
119
+ "checks": result.checks,
120
+ "review_items": result.review_items,
121
+ "exit_code": result.exit_code,
122
+ }
123
+ print(json.dumps(payload, indent=2))
124
+ else:
125
+ print(f"repo: {path}")
126
+ print(f"branch: {result.branch or '(local only)'}")
127
+ print(f"pr: {result.pr_url or '(not opened)'}")
128
+ print(f"touched: {len(result.touched)} files")
129
+ print(f"exit_code: {result.exit_code}")
130
+
131
+ return result.exit_code
132
+
133
+
134
+ def main(argv=None):
135
+ parser = _build_parser()
136
+ args = parser.parse_args(argv)
137
+ if args.command == "scan":
138
+ return _cmd_scan(args)
139
+ if args.command == "migrate":
140
+ return _cmd_migrate(args)
141
+ return 2
142
+
143
+
144
+ if __name__ == "__main__":
145
+ sys.exit(main())
@@ -0,0 +1,24 @@
1
+ """A scan finding: one Fireworks touchpoint and how the migration will handle it."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any, Dict
7
+
8
+
9
+ @dataclass
10
+ class Finding:
11
+ classification: str # MIGRATE | BLOCK | REVIEW
12
+ file: str
13
+ line: int
14
+ kind: str
15
+ detail: str
16
+
17
+ def to_dict(self) -> Dict[str, Any]:
18
+ return {
19
+ "class": self.classification,
20
+ "file": self.file,
21
+ "line": self.line,
22
+ "kind": self.kind,
23
+ "detail": self.detail,
24
+ }