# -*- coding: utf-8 -*- """erabu ── 頭脳が自分で道具を選ぶ(2026-09-17・本人「LLM がカーネルの仕組みを直接使えないと意味がない」)。 今まで: 本人の文 → 決まった言い方(正規表現)→ 道具。頭脳は選べなかった。 これから: 雑談の頼み文に【使える道具】の一覧(用件と 例の言い方)を付け、 道具で済む頼みなら 頭脳は返事の代わりに 1行だけ `道具: <例のような言い方>` と書く。 その言い方を machine.match に通す(=許可表の中の用件しか動かない。頭脳にシェルは渡さない)。 承認の札(外・跡)は今まで通り main.route が出す。 ★ 頭脳が作れるのは「言い方」だけ。用件の名前を直接指定させないのは、 材料(語・数・宛先)の取り出しを machine の決まった読み方に任せるため。 """ from __future__ import annotations import os import re # 用件 → 例の言い方(頭脳に見せる。ここに無い用件は頭脳からは選べない=わざと) REI = [ ("いま何時", "いま何時?"), ("こよみ", "3日後は何曜日?/2026年1月6日の29日後は何月何日?/14時の2時間後は何時?"), ("世界時計", "ニューヨークは今何時?"), ("計算", "12×34は?"), ("天気", "天気は?/大阪の天気は?"), ("予定", "今日の予定は?/明日の予定は?"), ("リマインダー一覧", "リマインダーを見せて"), ("リマインダーに入れる", "「薬を飲む」をリマインダーに入れて"), ("メモを書く", "「牛乳を買う」とメモして"), ("メモを探す", "「買い物」のメモを探して"), ("ファイルを探す", "「請求書」というファイルを探して/「請求書」と書いてあるファイルを探して"), ("最近のファイル", "最近使ったファイルは?"), ("大きいファイル", "大きいファイルはどれ?"), ("フォルダの大きさ", "ダウンロードは何GB使ってる?"), ("選んでいるファイル", "Finderで選んでいるファイルは?"), ("未読メール", "未読メールは?"), ("メールを送る", "山田さんに「明日は10時に行きます」とメールして"), ("メッセージを送る", "田中さんに「遅れます」とメッセージして"), ("いまの曲", "いま流れてる曲は?"), ("音楽", "音楽を止めて/次の曲にして/音楽をかけて"), ("タイマー", "5分後に「休憩」と知らせて"), ("重いアプリ", "重いアプリは?"), ("電池", "電池は?"), ("空き容量", "空き容量は?"), ("メモリ", "メモリは?"), ("ネット", "ネットつながってる?"), ("ネットの速さ", "ネットの速さは?"), ("IPアドレス", "IPアドレスは?"), ("バックアップ", "バックアップはいつ?"), ("開いているアプリ", "開いているアプリは?"), ("アプリをひらく", "Safariを開いて/メモを開いて/電卓を開いて"), ("アプリを閉じる", "Safariを閉じて"), ("フォルダをひらく", "ダウンロードのフォルダを開いて"), ("ゴミ箱", "ゴミ箱はいくつ?"), ("最近のダウンロード", "最近のダウンロードは?"), ("音量", "音量は?"), ("音量をかえる", "音量を30にして"), ("消音", "ミュートして/音を戻して"), ("明るさ", "画面を明るくして/画面の明るさを下げて"), ("画面ロック", "画面をロックして"), ("画面を消す", "画面を消して"), ("見た目をかえる", "ダークモードにして"), ("設定を開く", "画面収録の設定を開いて/Bluetoothの設定を開いて"), ("ネットで調べる", "「○○」をネットで調べて"), ("ウィキペディア", "「○○」をウィキペディアで調べて"), ("辞書", "辞書で「憂鬱」を引いて"), ("読み上げる", "「こんにちは」と読み上げて"), ("知らせる", "「休憩」と知らせて"), ("クリップボード", "クリップボードは?"), ("コピーする", "「○○」をコピーして"), ("スクリーンショット", "スクリーンショットを撮って"), ("画面をよむ", "画面を読んで"), ("ショートカット一覧", "ショートカットの一覧を見せて"), ("ショートカットを実行", "「○○」というショートカットを実行して"), ("再起動", "再起動して"), ("電源を切る", "電源を切って"), ] # 用件の群(kimeru の 2段選び: まず群を 1桁、次に群の中を 1桁)。各群 9 まで・群も 9 まで(数字 1桁で答えさせるため) GUN = [ ("時刻・暦・計算・天気", ["いま何時", "こよみ", "世界時計", "計算", "天気"]), ("予定・リマインダー・メモ・タイマー", ["予定", "リマインダー一覧", "リマインダーに入れる", "メモを書く", "メモを探す", "タイマー", "知らせる"]), ("ファイル・フォルダ", ["ファイルを探す", "最近のファイル", "大きいファイル", "フォルダの大きさ", "選んでいるファイル", "フォルダをひらく", "ゴミ箱", "最近のダウンロード"]), ("メール・メッセージ", ["未読メール", "メールを送る", "メッセージを送る"]), ("音楽・音・読み上げ", ["いまの曲", "音楽", "音量", "音量をかえる", "消音", "読み上げる"]), ("パソコンの状態", ["重いアプリ", "電池", "空き容量", "メモリ", "バックアップ", "開いているアプリ", "IPアドレス"]), ("ネット・調べもの", ["ネット", "ネットの速さ", "ネットで調べる", "ウィキペディア", "辞書"]), ("画面・アプリ・設定", ["アプリをひらく", "アプリを閉じる", "明るさ", "画面ロック", "画面を消す", "見た目をかえる", "設定を開く", "スクリーンショット", "画面をよむ"]), ("その他", ["クリップボード", "コピーする", "ショートカット一覧", "ショートカットを実行", "再起動", "電源を切る"]), ] _REI = dict(REI) _ICHIRAN = {} def ichiran(gun: bool = False) -> str: """頭脳に見せる一覧(用件が machine に実在するものだけ)。1回作って使い回す(頼み文の頭に置くので、変えると読み直しになる)。 gun=True は 群ごと・番号つき(kimeru 用)。返事に「道具: 言い方」を書かせる元の形は 平らな一覧のまま(測った時の形を変えない)""" if gun not in _ICHIRAN: import machine if gun: gyou = [] for gi, (gna, names) in enumerate(GUN, 1): gyou.append("%d %s" % (gi, gna)) for ni, na in enumerate([n for n in names if n in machine.OPS], 1): gyou.append(" %d-%d %s: %s" % (gi, ni, na, _REI[na])) else: gyou = ["%s: %s" % (na, rei) for na, rei in REI if na in machine.OPS] _ICHIRAN[gun] = "\n".join(gyou) return _ICHIRAN[gun] # 元の教え(9/17 に測った文そのまま。返事の中に「道具: 言い方」と書かせる) OSHIE = ("【使える道具】(用件: 例の言い方)\n%s\n" "相手の頼みが上の道具で済むなら、返事を書かず 1行だけ「道具: <例のような言い方>」と書く" "(例: 道具: 5分後に「休憩」と知らせて)。相手が言った名前・数・言葉はそのまま言い方に入れる。" "あなたは今の日付・曜日・時刻・天気・電池・メール・ファイル・アプリの状態を知らず、計算も間違える。" "それらを聞かれたら自分で答えず必ず道具(例: 明後日は何曜?→道具: 2日後は何曜日?、傘いる?→道具: 天気は?、" "5分はかって→道具: 5分後に「時間です」と知らせて、まぶしい→道具: 画面の明るさを下げて、遅い・重い→道具: 重いアプリは?、" "あとどれくらい持つ→道具: 電池は?)。" "雑談・意見・説明・相談・思い出話は道具を使わず ふつうに答える。") # kimeru 用(一覧は群ごと・番号つき。「道具: 言い方」は書かせない= # ★ 2026-09-18 実測: これが在ると 番号を聞いても「道具」と書きたがり、数字に確率が乗らない(かさ 0.0〜0.2)) OSHIE_ICHIRAN = ("【使える道具】(番号 用件: 例の言い方)\n%s\n" "あなたは今の日付・曜日・時刻・天気・電池・メール・ファイル・アプリの状態を知らず、計算も間違える。" "それらは自分で答えず道具で調べる。") _DOUGU_GYOU = re.compile(r"^\s*道具\s*[::]\s*(.+?)\s*$", re.M) def oshie(kaku: bool = True) -> str: """頭脳に見せる教え。kaku=False は kimeru が番号で決める形(「道具: 言い方」を書かせない)""" return (OSHIE if kaku else OSHIE_ICHIRAN) % ichiran(gun=not kaku) def yomu(text: str, name: str = None): """頭脳の返事から「道具: 言い方」を取り出し、machine.match に通す。無ければ None、当たらなければ ("", 言い方)。 name(kimeru で決まった用件)があれば、言い方が決まった形でなくても その用件の材料取り(machine.zairyou)を通す""" m = _DOUGU_GYOU.search(text or "") if not m: return None iikata = m.group(1).strip().strip("「」『』\"'") import machine hit = machine.match(iikata) if hit and (not name or hit[0] == name): return hit if name: slots = zairyou(name, iikata) if slots is not None: return (name, slots) # 頭脳が「道具: 計算: 1234×56は?」と用件名を頭に付けることがある(実測 2/24)。用件名を外してもう一度 m2 = re.match(r"^\s*([^::\s]{1,14})\s*[::]\s*(.+)$", iikata) if m2 and m2.group(1) in machine.OPS: na, nokori = m2.group(1), m2.group(2).strip() hit = machine.match(nokori) if hit: return hit # 言い方が決まった形でなくても、用件名が合っていて材料が取れるなら通す(語=「」の中) slots = {"_文": nokori} q = machine._quoted(nokori) or nokori.strip("「」『』") if na in ("ファイルを探す", "メモを探す", "辞書", "ショートカットを実行", "ネットで調べる", "ウィキペディア"): slots["語"] = q elif na in ("メモを書く", "リマインダーに入れる", "読み上げる", "知らせる"): slots["文"] = q elif na in ("メールを送る", "メッセージを送る", "計算", "アプリをひらく", "音量をかえる"): return ("", iikata) # 材料の形が要るものは 決まった言い方でないと動かさない return (na, slots) return ("", iikata) # ══════════════════════════════════════════════════════════════════ # 1トークンで選ぶ(kimeru・2026-09-18)── Jev の「System One」を手元の頭脳で # ① 群を 1桁で選ぶ(0 = 道具は要らない) ② 群の中を 1桁で選ぶ(0 = どれでもない) # 自信 = p1 × p2。線(SEN)より低ければ 雑談として返事を作る(誤発動より取りこぼしを選ぶ) # ③ 材料: 文からそのまま取れれば(machine.zairyou)すぐ動かす。取れなければ 頭脳に「言い方」を 1行だけ書かせる # ══════════════════════════════════════════════════════════════════ SEN = float(os.environ.get("KERNEL_KIMERU_SEN", "0.5")) # 線。物差し(hakaru_kimeru)で測って決める TOI_GUN = "上の【今の発言】は、道具の群のどれで済む?" NASHI_GUN = "道具は要らない(雑談・意見・説明・相談・思い出話・相手が自分でする話)" TOI_NAKA = "群「%s」の中のどれ?" NASHI_NAKA = "どれでもない" TOI_BANGOU = ("上の【今の発言】は、一覧のどの道具で済む?番号だけを書く(例 8-3)。" "道具が要らない(雑談・意見・説明・相談・思い出話・相手が自分でする話)なら 0。") IIKATA_TOI = ("【言い方】上の【今の発言】は 道具「%s」で済む。相手の言った名前・数・言葉をそのまま入れて、" "一覧の例のような言い方に直し、1行だけ「道具: <言い方>」と書く。返事や説明は書かない。") TOI_NAMAE = ("上の【今の発言】は、一覧のどの道具で済む?用件の名前を1つだけ書く。" "道具が要らない(雑談・意見・説明・相談・思い出話・相手が自分でする話)なら なし。") NASHI = "なし" OSHIRI = os.environ.get("KERNEL_KIMERU_OSHIRI", "") # 答えの書き出し(「用件:」は空白を呼ぶので 空のまま) KENSA = os.environ.get("KERNEL_KIMERU_KENSA", "1") != "0" # 名前が出たら「本当にその道具を頼んでいる?」を はい/いいえ で確かめる TOI_KENSA = "相手は今、道具「%s」(例: %s)を使ってほしいと頼んでいる? 言葉が似ているだけ・雑談・意見・相談なら いいえ。" HOU = os.environ.get("KERNEL_KIMERU_HOU", "名前") # 名前(文法で縛る)/ 番号(群-番 1回)/ 2段(群→中) def kimeru_dougu(system: str, user: str, timeout: int = 180, hou: str = None) -> dict: """道具か雑談かと、道具ならどの用件かを、返事を書かせずに決める。 戻り値 {"用件", "群", "p1", "p2", "自信", "かさ1", "かさ2", "出た", "ms", "tokens"}(用件 None = 道具なし)""" import kimeru hou = hou or HOU if hou == "名前": names = [NASHI] + [n for _, ns in GUN for n in ns] r = kimeru.namae(system, user, TOI_NAMAE, names, timeout=timeout, oshiri=OSHIRI) na = r["名"] out = {"用件": None if na in (None, NASHI) else na, "群": None, "p1": r["p"], "p2": None, "自信": r["p"] if na else 0.0, "かさ1": r["かさ"], "かさ2": None, "出た": r["出た"][:12], "ms": r["ms"], "tokens": r.get("tokens")} if out["用件"]: out["群"] = next((g for g, ns in GUN if na in ns), None) if KENSA: r2 = kimeru.hai_iie(system, user, TOI_KENSA % (na, _REI.get(na, "")), timeout=timeout) out.update({"p2": round(r2["はい"], 3), "かさ2": round(r2["かさ"], 3), "ms": r["ms"] + r2["ms"], "自信": round(r["p"] * r2["はい"], 3) if r2["かさ"] > 0 else 0.0}) return out if hou == "2段": gnames = [g for g, _ in GUN] r1 = kimeru.n_taku(system, user, TOI_GUN, gnames, nashi=NASHI_GUN, timeout=timeout) out = {"用件": None, "群": r1["名"], "p1": round(r1["p"], 3), "p2": None, "自信": 0.0, "かさ1": round(r1["かさ"], 3), "かさ2": None, "出た": r1["先頭"][:12], "ms": r1["ms"], "tokens": r1.get("tokens")} if r1["名"] is None: out["自信"] = round(r1["p"], 3) return out names = GUN[gnames.index(r1["名"])][1] r2 = kimeru.n_taku(system, user, TOI_NAKA % r1["名"], names, nashi=NASHI_NAKA, timeout=timeout) out.update({"p2": round(r2["p"], 3), "ms": r1["ms"] + r2["ms"], "かさ2": round(r2["かさ"], 3)}) if r2["名"] is None: return out out["用件"] = r2["名"] out["自信"] = round(r1["p"] * r2["p"], 3) return out # 番号(群-番)1回 r = kimeru.bangou(system, user, TOI_BANGOU, timeout=timeout) out = {"用件": None, "群": None, "p1": r["p1"], "p2": r["p2"], "自信": 0.0, "かさ1": r["かさ1"], "かさ2": r["かさ2"], "出た": (r.get("出た") or "").strip()[:12], "ms": r["ms"], "tokens": r.get("tokens")} g, b = r["群"], r["番"] if g is None: out["自信"] = r["p1"] return out if not (1 <= g <= len(GUN)): return out out["群"] = GUN[g - 1][0] names = GUN[g - 1][1] if b is None or not (1 <= b <= len(names)): return out out["用件"] = names[b - 1] out["自信"] = round(r["p1"] * (r["p2"] or 0.0), 3) return out def zairyou(name: str, text: str): """用件が決まった後の材料。文からそのまま取れれば辞書、取れなければ None(→ 頭脳に言い方を作らせる)""" import machine try: return machine.zairyou(name, text) except Exception: return None